How to use stack contents in LLDB breakpoint state?

Problem:

I have a situation where during startup we have multimedia playback, and objc_exception_throw () takes about 5 times over this period, but is always caught and located to the south of the media player object.

I’m tired either (a) of manually continuing n times, or (b) leaving disabled breakpoints until playback is complete.

What I tried:

  • make the breakpoint ignore the first five hits (problem: this is not always exactly five times)
  • creating my own symbolic breakpoint using my target as a module (problem: nothing has changed)

What I would like to do:

One solution that comes to mind is to evaluate the stack when a breakpoint is reached and continue if it specifies a specific method or function. But I do not know how to do this.

Other ideas are also welcome.

+7
source share
2 answers

You do this using Python.

The following is an ignore list and a function that you can attach as a command to a breakpoint.

The function captures function names in the backtrace and sets - intersects these names with the ignore list. If the names match, it continues the process. This effectively skips the transition to the debugger for unwanted stacks.

(lldb) b objc_exception_throw Breakpoint 1: where = libobjc.A.dylib`objc_exception_throw, address = 0x00000000000113c5 (lldb) script Python Interactive Interpreter. To exit, type 'quit()', 'exit()' or Ctrl-D. >>> ignored_functions = ['recurse_then_throw_and_catch'] def continue_ignored(frame, bp_loc, dict): global ignored_functions names = set([frame.GetFunctionName() for frame in frame.GetThread()]) all_ignored = set(ignored_functions) ignored_here = all_ignored.intersection(names) if len(ignored_here) > 0: frame.GetThread().GetProcess().Continue() quit() (lldb) br comm add -F continue_ignored 1 (lldb) r 

I tried this against the following file, and it successfully skips the first throw inside recurse_then_throw_and_catch and gets into the debugger during the throw inside throw_for_real .

 #import <Foundation/Foundation.h> void f(int n) { if (n <= 0) @throw [NSException exceptionWithName:@"plugh" reason:@"foo" userInfo:nil]; f(n - 1); } void recurse_then_throw_and_catch(void) { @try { f(5); } @catch (NSException *e) { NSLog(@"Don't care: %@", e); } } void throw_for_real(void) { f(2); } int main(void) { recurse_then_throw_and_catch(); throw_for_real(); } 

I assume that you can add this function to your .lldbinit and then connect it to breakpoints as needed from the console. (I do not think you can install the script command from Xcode.)

+12
source
 break command add -s python -o "return any('xyz' in f.name for f in frame.thread)" 

If the python shutdown command returns False , lldb will continue to work. So this says: if any frame on the stack has the string 'xyz' in its name, then returns True (to stop). Otherwise, if no frames have this name, this any expression will return False (to continue).

+1
source

All Articles