@@ -13,6 +13,7 @@ local thread = require 'bee.thread'
1313local fs = require ' backend.worker.filesystem'
1414local log = require ' common.log'
1515local channel = require " bee.channel"
16+ local disassemble = require ' backend.worker.disassemble'
1617local initialized = false
1718local suspend = false
1819local info = {}
@@ -197,6 +198,12 @@ local function stackTrace(res, coid, start, levels)
197198 }
198199 if info .what ~= ' C' then
199200 r .column = 1
201+ if rdebug .currentpc then
202+ local pc = rdebug .currentpc (depth )
203+ if pc >= 0 then
204+ r .instructionPointerReference = (" inst_%dx%dx%d" ):format (coid , depth , pc )
205+ end
206+ end
200207 local src = source .create (info .source )
201208 if source .valid (src ) then
202209 r .line = source .line (src , info .currentline )
@@ -572,6 +579,95 @@ function CMD.customRequestShowIntegerAsHex()
572579 }
573580end
574581
582+ function CMD .disassemble (pkg )
583+ if not rdebug .dumpproto then
584+ sendToMaster ' disassemble' {
585+ command = pkg .command ,
586+ seq = pkg .seq ,
587+ success = false ,
588+ message = " Disassemble not supported for this Lua version" ,
589+ }
590+ return
591+ end
592+ local proto
593+ local defaultOffset = 0
594+ local refId = pkg .refId
595+ if type (refId ) == " string" and refId :match (" ^%d+x%d+x%d+$" ) then
596+ local coid , depth , pc = refId :match (" ^(%d+)x(%d+)x(%d+)$" )
597+ -- navigate to the correct coroutine
598+ local L = baseL
599+ for _ = 0 , tonumber (coid ) - 1 do
600+ L = coroutineFrom (L )
601+ if not L then break end
602+ end
603+ if L then
604+ hookmgr .sethost (L )
605+ proto = rdebug .dumpproto (tonumber (depth ))
606+ hookmgr .sethost (baseL )
607+ end
608+ defaultOffset = tonumber (pc )
609+ end
610+ if not proto then
611+ local rtype , ref = variables .resolveMemoryRef (tonumber (refId ))
612+ if ref and rtype == " function" then
613+ proto = rdebug .dumpproto (ref )
614+ end
615+ end
616+ if not proto or not proto .code or # proto .code == 0 then
617+ sendToMaster ' disassemble' {
618+ command = pkg .command ,
619+ seq = pkg .seq ,
620+ success = false ,
621+ message = " Cannot dump function" ,
622+ }
623+ return
624+ end
625+ local instructions = disassemble .disassemble_function (proto , luaver .LUAVERSION )
626+ local byteOffset = math.floor ((pkg .offset or 0 ) / 4 )
627+ local instOffset = defaultOffset + byteOffset + (pkg .instructionOffset or 0 )
628+ local instCount = pkg .instructionCount or # instructions
629+ local result = {}
630+ local firstLocation = nil
631+ if proto .source then
632+ local src = source .create (proto .source )
633+ if source .valid (src ) then
634+ firstLocation = source .output (src )
635+ end
636+ end
637+ local start = math.max (1 , instOffset + 1 )
638+ for i = start , math.min (start + instCount - 1 , # instructions ) do
639+ local inst = instructions [i ]
640+ local r = {
641+ address = inst .address ,
642+ instructionBytes = inst .instructionBytes ,
643+ instruction = inst .opName .. " " .. inst .operands ,
644+ }
645+ if inst .line then
646+ r .line = inst .line
647+ r .column = 1
648+ end
649+ if inst .symbol then
650+ r .symbol = inst .symbol
651+ end
652+ if inst .presentationHint then
653+ r .presentationHint = inst .presentationHint
654+ end
655+ if firstLocation then
656+ r .location = firstLocation
657+ firstLocation = nil
658+ end
659+ result [# result + 1 ] = r
660+ end
661+ sendToMaster ' disassemble' {
662+ command = pkg .command ,
663+ seq = pkg .seq ,
664+ success = true ,
665+ body = {
666+ instructions = result ,
667+ },
668+ }
669+ end
670+
575671local function runLoop (reason , level )
576672 baseL = hookmgr .gethost ()
577673 -- TODO: 只在lua栈帧时需要text?
0 commit comments