How to prolong or duplicate a backstop breakpoint

I adapted the AppleObjcTrampolineHandler to my runtime. It works in as
much as that the debugger steps over my intermediate C functions and
breaks in the targetted method.

Unfortunately when I step out of the method, I am not back at the ObjC
call (0x0000000100000ebf) but instead in my intermediate function. I
think this is, because I am not using trampolines (jumps) but plain C

When I turn on `log enabled lldb step` and watch what is hapenning when
lldb steps through to -[foo class] (0x0000000100000df0)
I can see this at one point in time on the thread plan stack:

  thread #1: tid = 0x8c74:
    Active plan stack:
      Element 0: Base thread plan.
      Element 1: Stepping in through line class.m:44 using

This is really an orthogonal problem to the thread plans. They are about answering the question "how do I get from A to B?". But you want to get the right answer to "If I land in B, do I want to stop there?" This sort of question is answered with the "ShouldStopHere" mechanism (see source/Target/ThreadPlanShouldStopHere.cpp). Then the Thread Plans will invoke this mechanism whenever they are about to stop and return control to the user, and the should stop here will decide whether to stop, and if you aren't going to stop, how to get out of the "bad" place.

I had to solve pretty much your problem for Swift thunks, which are much like your ObjC dispatch functions. Apparently that's a bit of code I missed when we were moving the generic changes for swift back to

If you look at the Swift version of lldb:

You will see I added this bit to the DefaultShouldStopHereCallback (around line 88):

  // Check whether the frame we are in is a language runtime thunk, only for
  // step out:
  if (operation == eFrameCompareOlder) {
    Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
    if (symbol) {
      LanguageRuntime *language_runtime;
      bool is_thunk = false;
      ProcessSP process_sp(current_plan->GetThread().GetProcess());
      enum LanguageType languages_to_try = {
          eLanguageTypeSwift, eLanguageTypeObjC, eLanguageTypeC_plus_plus};

      for (enum LanguageType language : languages_to_try) {
        language_runtime = process_sp->GetLanguageRuntime(language);
        if (language_runtime)
          is_thunk = language_runtime->IsSymbolARuntimeThunk(*symbol);
        if (is_thunk) {
          should_stop_here = false;

I am pretty sure you should just be able to add this directly to the lldb, and then have your LanguageRuntime reply true to the IsSymbolARuntimeThunk when the symbol is your dispatch function. Then the rest of the machinery will take care of getting you out of there.


Hi Jim,

Thanks! I didn't know about ThreadPlanShouldStopHere. And your
swift-lldb code does exactly, what I am looking for.