@@ -2541,25 +2541,26 @@ void Target::SetAllStopHooksActiveState(bool active_state) {
2541
2541
}
2542
2542
}
2543
2543
2544
- void Target::RunStopHooks () {
2544
+ bool Target::RunStopHooks () {
2545
2545
if (m_suppress_stop_hooks)
2546
- return ;
2546
+ return false ;
2547
2547
2548
2548
if (!m_process_sp)
2549
- return ;
2549
+ return false ;
2550
2550
2551
2551
// Somebody might have restarted the process:
2552
+ // Still return false, the return value is about US restarting the target.
2552
2553
if (m_process_sp->GetState () != eStateStopped)
2553
- return ;
2554
+ return false ;
2554
2555
2555
2556
// <rdar://problem/12027563> make sure we check that we are not stopped
2556
2557
// because of us running a user expression since in that case we do not want
2557
2558
// to run the stop-hooks
2558
2559
if (m_process_sp->GetModIDRef ().IsLastResumeForUserExpression ())
2559
- return ;
2560
+ return false ;
2560
2561
2561
2562
if (m_stop_hooks.empty ())
2562
- return ;
2563
+ return false ;
2563
2564
2564
2565
// If there aren't any active stop hooks, don't bother either.
2565
2566
bool any_active_hooks = false ;
@@ -2570,7 +2571,7 @@ void Target::RunStopHooks() {
2570
2571
}
2571
2572
}
2572
2573
if (!any_active_hooks)
2573
- return ;
2574
+ return false ;
2574
2575
2575
2576
std::vector<ExecutionContext> exc_ctx_with_reasons;
2576
2577
@@ -2588,7 +2589,7 @@ void Target::RunStopHooks() {
2588
2589
// If no threads stopped for a reason, don't run the stop-hooks.
2589
2590
size_t num_exe_ctx = exc_ctx_with_reasons.size ();
2590
2591
if (num_exe_ctx == 0 )
2591
- return ;
2592
+ return false ;
2592
2593
2593
2594
StreamSP output_sp = m_debugger.GetAsyncOutputStream ();
2594
2595
@@ -2636,22 +2637,27 @@ void Target::RunStopHooks() {
2636
2637
output_sp->Printf (" -- Thread %d\n " ,
2637
2638
exc_ctx.GetThreadPtr ()->GetIndexID ());
2638
2639
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 ;
2644
2643
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 ;
2648
2652
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.
2655
2661
output_sp->Printf (" \n Aborting stop hooks, hook %" PRIu64
2656
2662
" set the program running.\n "
2657
2663
" Consider using '-G true' to make "
@@ -2660,16 +2666,42 @@ void Target::RunStopHooks() {
2660
2666
somebody_restarted = true ;
2661
2667
break ;
2662
2668
}
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;
2663
2679
}
2664
2680
}
2665
2681
2666
2682
output_sp->Flush ();
2667
2683
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
+
2668
2689
// Finally, if auto-continue was requested, do it now:
2669
2690
// We only compute should_stop against the hook results if a hook got to run
2670
2691
// 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 ;
2673
2705
}
2674
2706
2675
2707
const TargetPropertiesSP &Target::GetGlobalProperties () {
@@ -3235,13 +3267,14 @@ void Target::StopHookCommandLine::SetActionFromStrings(
3235
3267
GetCommands ().AppendString (string.c_str ());
3236
3268
}
3237
3269
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) {
3240
3273
assert (exc_ctx.GetTargetPtr () && " Can't call PerformAction on a context "
3241
3274
" with no target" );
3242
3275
3243
3276
if (!m_commands.GetSize ())
3244
- return true ;
3277
+ return StopHookResult::KeepStopped ;
3245
3278
3246
3279
CommandReturnObject result (false );
3247
3280
result.SetImmediateOutputStream (output_sp);
@@ -3260,8 +3293,11 @@ bool Target::StopHookCommandLine::HandleStop(ExecutionContext &exc_ctx,
3260
3293
debugger.GetCommandInterpreter ().HandleCommands (GetCommands (), &exc_ctx,
3261
3294
options, result);
3262
3295
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;
3265
3301
}
3266
3302
3267
3303
// Target::StopHookScripted
@@ -3289,20 +3325,22 @@ Status Target::StopHookScripted::SetScriptCallback(
3289
3325
return error;
3290
3326
}
3291
3327
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) {
3294
3331
assert (exc_ctx.GetTargetPtr () && " Can't call HandleStop on a context "
3295
3332
" with no target" );
3296
3333
3297
3334
ScriptInterpreter *script_interp =
3298
3335
GetTarget ()->GetDebugger ().GetScriptInterpreter ();
3299
3336
if (!script_interp)
3300
- return true ;
3337
+ return StopHookResult::KeepStopped ;
3301
3338
3302
3339
bool should_stop = script_interp->ScriptedStopHookHandleStop (
3303
3340
m_implementation_sp, exc_ctx, output_sp);
3304
3341
3305
- return should_stop;
3342
+ return should_stop ? StopHookResult::KeepStopped
3343
+ : StopHookResult::RequestContinue;
3306
3344
}
3307
3345
3308
3346
void Target::StopHookScripted::GetSubclassDescription (
0 commit comments