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

后端 未结 2 1628
盖世英雄少女心
盖世英雄少女心 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:31
    break command add -s python -o "return any('xyz' in f.name for f in frame.thread)"
    

    If a python breakpoint command returns False, lldb will keep going. So this is saying: if any frame in the stack has the string 'xyz' in its name, then return True (to stop). Otherwise if no frame has that name, this any expression will return False (to keep going).

    0 讨论(0)
  • 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 <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 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.)

    0 讨论(0)
提交回复
热议问题