~pali/llvm/lldb-trunk

« back to all changes in this revision

Viewing changes to source/Target/Target.cpp

  • Committer: jingham
  • Date: 2019-02-23 00:13:25 UTC
  • Revision ID: svn-v4:91177308-0d34-0410-b5e6-96231b3b80d8:lldb/trunk:354706
Make sure that stop-hooks run asynchronously.

They aren't designed to nest recursively, so this will prevent that.
Also add a --auto-continue flag, putting "continue" in the stop hook makes
the stop hooks fight one another in multi-threaded programs.
Also allow more than one -o options so you can make more complex stop hooks w/o
having to go into the editor.

<rdar://problem/48115661>

Differential Revision: https://reviews.llvm.org/D58394

Show diffs side-by-side

added added

removed removed

Lines of Context:
2554
2554
 
2555
2555
  StopHookCollection::iterator pos, end = m_stop_hooks.end();
2556
2556
 
2557
 
  // If there aren't any active stop hooks, don't bother either:
 
2557
  // If there aren't any active stop hooks, don't bother either.
 
2558
  // Also see if any of the active hooks want to auto-continue.
2558
2559
  bool any_active_hooks = false;
2559
 
  for (pos = m_stop_hooks.begin(); pos != end; pos++) {
2560
 
    if ((*pos).second->IsActive()) {
 
2560
  bool auto_continue = false;
 
2561
  for (auto hook : m_stop_hooks) {
 
2562
    if (hook.second->IsActive()) {
2561
2563
      any_active_hooks = true;
2562
 
      break;
 
2564
      auto_continue |= hook.second->GetAutoContinue();
2563
2565
    }
2564
2566
  }
2565
2567
  if (!any_active_hooks)
2595
2597
  bool hooks_ran = false;
2596
2598
  bool print_hook_header = (m_stop_hooks.size() != 1);
2597
2599
  bool print_thread_header = (num_exe_ctx != 1);
 
2600
  bool did_restart = false;
2598
2601
 
2599
2602
  for (pos = m_stop_hooks.begin(); keep_going && pos != end; pos++) {
2600
2603
    // result.Clear();
2639
2642
        options.SetPrintResults(true);
2640
2643
        options.SetAddToHistory(false);
2641
2644
 
 
2645
        // Force Async:
 
2646
        bool old_async = GetDebugger().GetAsyncExecution();
 
2647
        GetDebugger().SetAsyncExecution(true);
2642
2648
        GetDebugger().GetCommandInterpreter().HandleCommands(
2643
2649
            cur_hook_sp->GetCommands(), &exc_ctx_with_reasons[i], options,
2644
2650
            result);
2645
 
 
 
2651
        GetDebugger().SetAsyncExecution(old_async);
2646
2652
        // If the command started the target going again, we should bag out of
2647
2653
        // running the stop hooks.
2648
2654
        if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
2651
2657
          StopHookCollection::iterator tmp = pos;
2652
2658
          if (++tmp != end)
2653
2659
            result.AppendMessageWithFormat("\nAborting stop hooks, hook %" PRIu64
2654
 
                                           " set the program running.\n",
 
2660
                                           " set the program running.\n"
 
2661
                                           "  Consider using '-G true' to make "
 
2662
                                           "stop hooks auto-continue.\n",
2655
2663
                                           cur_hook_sp->GetID());
2656
2664
          keep_going = false;
 
2665
          did_restart = true;
2657
2666
        }
2658
2667
      }
2659
2668
    }
2660
2669
  }
 
2670
  // Finally, if auto-continue was requested, do it now:
 
2671
  if (!did_restart && auto_continue)
 
2672
    m_process_sp->PrivateResume();
2661
2673
 
2662
2674
  result.GetImmediateOutputStream()->Flush();
2663
2675
  result.GetImmediateErrorStream()->Flush();
3143
3155
//--------------------------------------------------------------
3144
3156
Target::StopHook::StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid)
3145
3157
    : UserID(uid), m_target_sp(target_sp), m_commands(), m_specifier_sp(),
3146
 
      m_thread_spec_up(), m_active(true) {}
 
3158
      m_thread_spec_up() {}
3147
3159
 
3148
3160
Target::StopHook::StopHook(const StopHook &rhs)
3149
3161
    : UserID(rhs.GetID()), m_target_sp(rhs.m_target_sp),
3150
3162
      m_commands(rhs.m_commands), m_specifier_sp(rhs.m_specifier_sp),
3151
 
      m_thread_spec_up(), m_active(rhs.m_active) {
 
3163
      m_thread_spec_up(), m_active(rhs.m_active),
 
3164
      m_auto_continue(rhs.m_auto_continue) {
3152
3165
  if (rhs.m_thread_spec_up)
3153
3166
    m_thread_spec_up.reset(new ThreadSpec(*rhs.m_thread_spec_up));
3154
3167
}
3175
3188
  else
3176
3189
    s->Indent("State: disabled\n");
3177
3190
 
 
3191
  if (m_auto_continue)
 
3192
    s->Indent("AutoContinue on\n");
 
3193
 
3178
3194
  if (m_specifier_sp) {
3179
3195
    s->Indent();
3180
3196
    s->PutCString("Specifier:\n");