Advertisement
LBPHacker

CC Stacktrace

Sep 10th, 2015
450
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 2.43 KB | None | 0 0
  1. local args = {...}
  2. local switches = {}
  3. local _fsopen = fs.open
  4.  
  5. local UNIQUECHUNKNAME = "trace/root"
  6.  
  7. local function printHelp()
  8.     local pname = shell.getRunningProgram()
  9.     print("Usage: " .. (pname:match("/(.-)$") or pname) .. " [switches...] <program> [args...]")
  10.     print("Switches:")
  11.     print("  -h         show this message")
  12.     print("  -l<FILE>   log trace to <FILE> (append mode)")
  13.     print("  -f         show full trace (including bios.lua)")
  14.     print("  -m<MAX>    set max trace depth to <MAX>")
  15.     print("                (there's no maximum by default)")
  16.     print("  -b         break trace into separate lines")
  17. end
  18.  
  19. local logfile
  20. function switches.l(rest)
  21.     logfile = rest
  22. end
  23.  
  24. function switches.h()
  25.     printHelp()
  26.     return true -- exit
  27. end
  28.  
  29. local maxdepth
  30. function switches.m(rest)
  31.     maxdepth = tonumber(rest)
  32.     if not maxdepth or maxdepth < 1 then
  33.         print("Invalid max depth: " .. rest)
  34.     end
  35. end
  36.  
  37. local breakintolines
  38. function switches.b()
  39.     breakintolines = true
  40. end
  41.  
  42. local fulltrace
  43. function switches.f()
  44.     fulltrace = true
  45. end
  46.  
  47. while args[1] do
  48.     if not args[1]:match("^%-") then break end
  49.     local switchf = args[1]:sub(2, 2)
  50.     if switches[switchf] then
  51.         if switches[switchf](args[1]:sub(3)) then return end
  52.     else
  53.         print("Unknown switch: " .. switchf)
  54.     end
  55.     table.remove(args, 1)
  56. end
  57.  
  58. if not args[1] then
  59.     printHelp()
  60.     return
  61. end
  62.  
  63. local ffunc = loadfile(args[1], setmetatable({shell = shell}, {__index = _G}))
  64. if not ffunc then
  65.     print("Failed to load program")
  66.     return
  67. end
  68.  
  69. load([[xpcall(func, handler)]], UNIQUECHUNKNAME, "t", {
  70.     xpcall = xpcall,
  71.     func = function()
  72.         ffunc(table.unpack(args, 2))
  73.     end,
  74.     handler = function(xpcallerr)
  75.         local loghandle
  76.         if logfile then
  77.             loghandle = _fsopen(logfile, "a")
  78.         end
  79.        
  80.         local tracerestbl = {xpcallerr .. "\n  stack trace:"}
  81.         local level = 1
  82.         while true do
  83.             local nope, errstr = pcall(error, "@", level + 2)
  84.             if errstr == "@" then break end
  85.             if not fulltrace and errstr:match("^(.-):") == UNIQUECHUNKNAME then
  86.                 tracerestbl[#tracerestbl] = nil
  87.                 tracerestbl[#tracerestbl] = nil -- yup, twice
  88.                 break
  89.             end
  90.             tracerestbl[#tracerestbl + 1] = errstr:match("^(.+): @$")
  91.             if level == maxdepth then break end
  92.             level = level + 1
  93.         end
  94.        
  95.         local traceres = table.concat(tracerestbl, breakintolines and "\n    " or " ")
  96.        
  97.         printError(traceres)
  98.         if loghandle then
  99.             loghandle.writeLine(traceres)
  100.             loghandle.close()
  101.         end
  102.     end
  103. })()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement