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.)
Jeremy W. Sherman
source share