Nikita, There was a lot of other stuff in that scripted_step.py beyond the plan class itself. I didn't follow what that did altogether. But if I removed all that stuff, and changed your plan slightly to not rely on the global TARGET and START_ADDRESS (I attached my simplified version below), then I can do either:
> lldb main -o "command script import /tmp/scripted_step.py" -o "break set -n > main" -o run (lldb) target create "main" Current executable set to 'main' (x86_64). (lldb) command script import /tmp/scripted_step.py (lldb) break set -n main Breakpoint 1: where = main`main + 15 at main.c:5:5, address = 0x0000000100000f5f (lldb) run Process 93318 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000f5f main`main at main.c:5 2 3 int main() 4 { -> 5 printf("Hello, world!\n"); ^ 6 return 0; 7 } 8 Target 0: (main) stopped. Process 93318 launched: '/tmp/main' (x86_64) (lldb) thread step-scripted -C scripted_step.SimpleStep init init done should step should stop 0x100000f66: mov al, 0x0 ; main:5 should stop done: False should step explains stop explains stop done: True should stop 0x100000f68: call 0x100000f7a ; main:5 should stop done: False should step explains stop explains stop done: True should stop should stop done: True Process 93318 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = Python thread plan implemented by class scripted_step.SimpleStep. frame #0: 0x0000000100000f7a main`printf main`printf: 0x100000f7a <+0>: jmpq *0x1080(%rip) ; (void *)0x0000000100000f90 0x100000f80: leaq 0x1081(%rip), %r11 ; _dyld_private 0x100000f87: pushq %r11 0x100000f89: jmpq *0x71(%rip) ; (void *)0x00007fff69523184: dyld_stub_binder Target 0: (main) stopped. or using the Python API: (lldb) script lldb.thread.StepUsingScriptedThreadPlan("scripted_step.SimpleStep") init init done should step ... with the same results. Does that simple use of the scripted plan also work for you? Jim
from __future__ import print_function import lldb import sys class SimpleStep: def __init__(self, thread_plan, dict_): print('init\n') self.thread_plan = thread_plan self.start_addr = thread_plan.GetThread().GetFrameAtIndex(0).GetPC() self.end_addr = self.start_addr + 26 # ret print('init done\n') def explains_stop(self, event): print('explains stop\n') stop_reason = self.thread_plan.GetThread().GetStopReason() # print('stop_reason: {}\n'.format(stop_reason)) if stop_reason == lldb.eStopReasonTrace: print('explains stop done: True\n') return True else: print('explains stop done: False\n') return False def should_stop(self, event): print('should stop\n') cur_pc = self.thread_plan.GetThread().GetFrameAtIndex(0).GetPC() if cur_pc < self.start_addr or cur_pc >= self.end_addr: #if cur_pc == self.end_addr: self.thread_plan.SetPlanComplete(True) print('should stop done: True\n') return True else: # print('in range\n') process = self.thread_plan.GetThread().GetProcess() thread = process.GetSelectedThread() frame = thread.GetSelectedFrame() pc = frame.GetPCAddress() func_name = pc.GetFunction().name line_num = pc.GetLineEntry().line insns = process.target.ReadInstructions(pc, 1, 'intel') insn = insns.GetInstructionAtIndex(0) mnemonic = insn.mnemonic operands = insn.operands if func_name: file_str = '{}; {}:{}'.format(' ' * 2, func_name, line_num) else: file_str = '' print('0x{:08x}: {} {}{}\n' .format(pc.load_addr, mnemonic, operands, file_str)) print('should stop done: False\n') return False def should_step(self): print('should step\n') return True
> On Sep 23, 2019, at 11:51 PM, Nikita Karetnikov <nik...@karetnikov.org> wrote: > > Jim, > > >> Not sure if my current version of 'SimpleStep' is correct (I've made a few > >> changes since testing via 'thread step-scripted'), but nothing happens (no > >> prints on '__init__') when I add the class via > >> 'StepUsingScriptedThreadPlan' in > >> the callback. > >> > >> What's the proper way to do this? > >> > > > > What happens? Did you look at the "step" log to see what lldb thought it > > was > > doing - i.e. "log enable -f /tmp/lldb-step-log.txt lldb step". Also, what > > is > > lldb doing then nothing happens? > > Apologies, by "nothing" I meant that the class code doesn't seem to be > invoked. > Here's the output: > > (lldb) log enable -f /tmp/lldb-step-log.txt lldb step > (lldb) breakpoint delete > About to delete all breakpoints, do you want to do that?: [Y/n] y > All breakpoints removed. (1 breakpoint) > (lldb) command script import scripted_step.py > Process 37849 stopped > * thread #1, stop reason = signal SIGSTOP > frame #0: 0x000000010255e000 dyld`_dyld_start > dyld`_dyld_start: > -> 0x10255e000 <+0>: pop rdi > 0x10255e001 <+1>: push 0x0 > 0x10255e003 <+3>: mov rbp, rsp > 0x10255e006 <+6>: and rsp, -0x10 > (lldb) trace > trace done > Hello, world! > Process 37849 exited with status = 0 (0x00000000) > > Note that the "trace" messages are printed, but nothing from the class in > between. > > I'm also attaching the lldb step log for this run. The SimpleStep class is > referenced in the log, but it's hard for me to understand what's going on > since > I'm not familiar with the internals of lldb. Do you see the problem? > > Have you tried reproducing this? debugserver just runs a "Hello, world!" > program: > > debugserver localhost:8000 main > > > One thing I've recently found (in some other work I've been doing) is that > > if > > you run the step asynchronously, then the call that ran the thread plan > > still > > holds the API lock, and any calls the scripted thread plan makes block > > against > > the other plan holding the lock. > > > > We already have a workaround for getting the "run lock" in Python code run > > for > > internal purposes. That is a bit of a hack, using the notion that the > > internal > > state thread is always running code on behalf of the agent that had the API > > lock - even though it is running on a separate thread. So we make a > > separate > > run lock for the internal state thread, and use that for code running on > > that > > thread. We probably need to do the same thing for the Target API lock. > > If it turns out to be relevant, will you be able to share this patch? If you > don't want to add it to the tree, can you at least share it on the list? > > Thanks, > Nikita > > <lldb-step-log.txt>
_______________________________________________ lldb-dev mailing list lldb-dev@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev