How do I use stack content in an LLDB breakpoint condition?

后端 未结 2 1641
盖世英雄少女心
盖世英雄少女心 2021-01-02 05:10

The problem:

I\'ve got a situation where we have a media playback during launch, and objc_exception_throw() hits about 5 times during that period, b

2条回答
  •  再見小時候
    2021-01-02 05:43

    You do it using Python.

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

    The function grabs the names of functions in the backtrace and set-intersects those names with the ignore list. If any names match, it continues running the process. This effectively skips dropping into 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 it against the following file, and it successfully skips the first throw inside recurse_then_throw_and_catch and drops into the debugger during the throw inside throw_for_real.

    #import 
    
    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 imagine you could add this function to your .lldbinit and then connect it to breakpoints as needed from the console. (I don't think you can set a script command from within Xcode.)

提交回复
热议问题