@@ -2541,25 +2541,26 @@ void Target::SetAllStopHooksActiveState(bool active_state) {
25412541 }
25422542}
25432543
2544- void Target::RunStopHooks () {
2544+ bool Target::RunStopHooks () {
25452545 if (m_suppress_stop_hooks)
2546- return ;
2546+ return false ;
25472547
25482548 if (!m_process_sp)
2549- return ;
2549+ return false ;
25502550
25512551 // Somebody might have restarted the process:
2552+ // Still return false, the return value is about US restarting the target.
25522553 if (m_process_sp->GetState () != eStateStopped)
2553- return ;
2554+ return false ;
25542555
25552556 // <rdar://problem/12027563> make sure we check that we are not stopped
25562557 // because of us running a user expression since in that case we do not want
25572558 // to run the stop-hooks
25582559 if (m_process_sp->GetModIDRef ().IsLastResumeForUserExpression ())
2559- return ;
2560+ return false ;
25602561
25612562 if (m_stop_hooks.empty ())
2562- return ;
2563+ return false ;
25632564
25642565 // If there aren't any active stop hooks, don't bother either.
25652566 bool any_active_hooks = false ;
@@ -2570,7 +2571,7 @@ void Target::RunStopHooks() {
25702571 }
25712572 }
25722573 if (!any_active_hooks)
2573- return ;
2574+ return false ;
25742575
25752576 std::vector<ExecutionContext> exc_ctx_with_reasons;
25762577
@@ -2588,7 +2589,7 @@ void Target::RunStopHooks() {
25882589 // If no threads stopped for a reason, don't run the stop-hooks.
25892590 size_t num_exe_ctx = exc_ctx_with_reasons.size ();
25902591 if (num_exe_ctx == 0 )
2591- return ;
2592+ return false ;
25922593
25932594 StreamSP output_sp = m_debugger.GetAsyncOutputStream ();
25942595
@@ -2636,22 +2637,27 @@ void Target::RunStopHooks() {
26362637 output_sp->Printf (" -- Thread %d\n " ,
26372638 exc_ctx.GetThreadPtr ()->GetIndexID ());
26382639
2639- bool this_should_stop = cur_hook_sp->HandleStop (exc_ctx, output_sp);
2640- // If this hook is set to auto-continue that should override the
2641- // HandleStop result...
2642- if (cur_hook_sp->GetAutoContinue ())
2643- this_should_stop = false ;
2640+ StopHook::StopHookResult this_result =
2641+ cur_hook_sp->HandleStop (exc_ctx, output_sp);
2642+ bool this_should_stop = true ;
26442643
2645- // If anybody wanted to stop, we should all stop.
2646- if (!should_stop)
2647- should_stop = this_should_stop;
2644+ switch (this_result) {
2645+ case StopHook::StopHookResult::KeepStopped:
2646+ // If this hook is set to auto-continue that should override the
2647+ // HandleStop result...
2648+ if (cur_hook_sp->GetAutoContinue ())
2649+ this_should_stop = false ;
2650+ else
2651+ this_should_stop = true ;
26482652
2649- // We don't have a good way to prohibit people from restarting the target
2650- // willy nilly in a stop hook. So see if the private state is running
2651- // here and bag out if it is.
2652- // FIXME: when we are doing non-stop mode for realz we'll have to instead
2653- // track each thread, and only bag out if a thread is set running.
2654- if (m_process_sp->GetPrivateState () != eStateStopped) {
2653+ break ;
2654+ case StopHook::StopHookResult::RequestContinue:
2655+ this_should_stop = false ;
2656+ break ;
2657+ case StopHook::StopHookResult::AlreadyContinued:
2658+ // We don't have a good way to prohibit people from restarting the
2659+ // target willy nilly in a stop hook. If the hook did so, give a
2660+ // gentle suggestion here and bag out if the hook processing.
26552661 output_sp->Printf (" \n Aborting stop hooks, hook %" PRIu64
26562662 " set the program running.\n "
26572663 " Consider using '-G true' to make "
@@ -2660,16 +2666,42 @@ void Target::RunStopHooks() {
26602666 somebody_restarted = true ;
26612667 break ;
26622668 }
2669+ // If we're already restarted, stop processing stop hooks.
2670+ // FIXME: if we are doing non-stop mode for real, we would have to
2671+ // check that OUR thread was restarted, otherwise we should keep
2672+ // processing stop hooks.
2673+ if (somebody_restarted)
2674+ break ;
2675+
2676+ // If anybody wanted to stop, we should all stop.
2677+ if (!should_stop)
2678+ should_stop = this_should_stop;
26632679 }
26642680 }
26652681
26662682 output_sp->Flush ();
26672683
2684+ // If one of the commands in the stop hook already restarted the target,
2685+ // report that fact.
2686+ if (somebody_restarted)
2687+ return true ;
2688+
26682689 // Finally, if auto-continue was requested, do it now:
26692690 // We only compute should_stop against the hook results if a hook got to run
26702691 // which is why we have to do this conjoint test.
2671- if (!somebody_restarted && ((hooks_ran && !should_stop) || auto_continue))
2672- m_process_sp->PrivateResume ();
2692+ if ((hooks_ran && !should_stop) || auto_continue) {
2693+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
2694+ Status error = m_process_sp->PrivateResume ();
2695+ if (error.Success ()) {
2696+ LLDB_LOG (log, " Resuming from RunStopHooks" );
2697+ return true ;
2698+ } else {
2699+ LLDB_LOG (log, " Resuming from RunStopHooks failed: {0}" , error);
2700+ return false ;
2701+ }
2702+ }
2703+
2704+ return false ;
26732705}
26742706
26752707const TargetPropertiesSP &Target::GetGlobalProperties () {
@@ -3235,13 +3267,14 @@ void Target::StopHookCommandLine::SetActionFromStrings(
32353267 GetCommands ().AppendString (string.c_str ());
32363268}
32373269
3238- bool Target::StopHookCommandLine::HandleStop (ExecutionContext &exc_ctx,
3239- StreamSP output_sp) {
3270+ Target::StopHook::StopHookResult
3271+ Target::StopHookCommandLine::HandleStop (ExecutionContext &exc_ctx,
3272+ StreamSP output_sp) {
32403273 assert (exc_ctx.GetTargetPtr () && " Can't call PerformAction on a context "
32413274 " with no target" );
32423275
32433276 if (!m_commands.GetSize ())
3244- return true ;
3277+ return StopHookResult::KeepStopped ;
32453278
32463279 CommandReturnObject result (false );
32473280 result.SetImmediateOutputStream (output_sp);
@@ -3260,8 +3293,11 @@ bool Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,
32603293 debugger.GetCommandInterpreter ().HandleCommands (GetCommands (), &exc_ctx,
32613294 options, result);
32623295 debugger.SetAsyncExecution (old_async);
3263-
3264- return true ;
3296+ lldb::ReturnStatus status = result.GetStatus ();
3297+ if (status == eReturnStatusSuccessContinuingNoResult ||
3298+ status == eReturnStatusSuccessContinuingResult)
3299+ return StopHookResult::AlreadyContinued;
3300+ return StopHookResult::KeepStopped;
32653301}
32663302
32673303// Target::StopHookScripted
@@ -3289,20 +3325,22 @@ Status Target::StopHookScripted::SetScriptCallback(
32893325 return error;
32903326}
32913327
3292- bool Target::StopHookScripted::HandleStop (ExecutionContext &exc_ctx,
3293- StreamSP output_sp) {
3328+ Target::StopHook::StopHookResult
3329+ Target::StopHookScripted::HandleStop (ExecutionContext &exc_ctx,
3330+ StreamSP output_sp) {
32943331 assert (exc_ctx.GetTargetPtr () && " Can't call HandleStop on a context "
32953332 " with no target" );
32963333
32973334 ScriptInterpreter *script_interp =
32983335 GetTarget ()->GetDebugger ().GetScriptInterpreter ();
32993336 if (!script_interp)
3300- return true ;
3337+ return StopHookResult::KeepStopped ;
33013338
33023339 bool should_stop = script_interp->ScriptedStopHookHandleStop (
33033340 m_implementation_sp, exc_ctx, output_sp);
33043341
3305- return should_stop;
3342+ return should_stop ? StopHookResult::KeepStopped
3343+ : StopHookResult::RequestContinue;
33063344}
33073345
33083346void Target::StopHookScripted::GetSubclassDescription (
0 commit comments