Index: lldb/include/lldb/Target/Process.h =================================================================== --- lldb/include/lldb/Target/Process.h +++ lldb/include/lldb/Target/Process.h @@ -83,6 +83,7 @@ bool GetWarningsOptimization() const; bool GetStopOnExec() const; std::chrono::seconds GetUtilityExpressionTimeout() const; + Timeout GetWatchdogTimeout() const; protected: Process *m_process; // Can be nullptr for global ProcessProperties Index: lldb/packages/Python/lldbsuite/test/lldbtest.py =================================================================== --- lldb/packages/Python/lldbsuite/test/lldbtest.py +++ lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -690,6 +690,9 @@ # First of all, clear all settings to have clean state of global properties. "settings clear -all", + # Set the timeout of 5 minutes for waiting a process to stop. + "settings set target.process.watchdog-timeout 300", + # Disable Spotlight lookup. The testsuite creates # different binaries with the same UUID, because they only # differ in the debug info, which is not being hashed. Index: lldb/source/Target/Process.cpp =================================================================== --- lldb/source/Target/Process.cpp +++ lldb/source/Target/Process.cpp @@ -241,6 +241,16 @@ return std::chrono::seconds(value); } +Timeout ProcessProperties::GetWatchdogTimeout() const { + const uint32_t idx = ePropertyWatchdogTimeout; + const uint64_t value = m_collection_sp->GetPropertyAtIndexAsUInt64( + nullptr, idx, g_process_properties[idx].default_uint_value); + if (value == 0) + return llvm::None; + + return std::chrono::seconds(value); +} + Status ProcessLaunchCommandOptions::SetOptionValue( uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) { @@ -727,8 +737,10 @@ if (state == eStateDetached || state == eStateExited) return state; + auto wait_timeout = timeout ? timeout : GetWatchdogTimeout(); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - LLDB_LOG(log, "timeout = {0}", timeout); + LLDB_LOG(log, "timeout = {0}", wait_timeout); if (!wait_always && StateIsStoppedState(state, true) && StateIsStoppedState(GetPrivateState(), true)) { @@ -745,7 +757,7 @@ while (state != eStateInvalid) { EventSP event_sp; - state = GetStateChangedEvents(event_sp, timeout, hijack_listener_sp); + state = GetStateChangedEvents(event_sp, wait_timeout, hijack_listener_sp); if (event_sp_ptr && event_sp) *event_sp_ptr = event_sp; @@ -1365,8 +1377,8 @@ Status error = PrivateResume(); if (error.Success()) { - StateType state = - WaitForProcessToStop(llvm::None, nullptr, true, listener_sp, stream); + StateType state = WaitForProcessToStop( + GetWatchdogTimeout(), nullptr, true, listener_sp, stream); const bool must_be_alive = false; // eStateExited is ok, so this must be false if (!StateIsStoppedState(state, must_be_alive)) Index: lldb/source/Target/TargetProperties.td =================================================================== --- lldb/source/Target/TargetProperties.td +++ lldb/source/Target/TargetProperties.td @@ -198,6 +198,9 @@ def UtilityExpressionTimeout: Property<"utility-expression-timeout", "UInt64">, DefaultUnsignedValue<15>, Desc<"The time in seconds to wait for LLDB-internal utility expressions.">; + def WatchdogTimeout: Property<"watchdog-timeout", "UInt64">, + DefaultUnsignedValue<0>, + Desc<"The time in seconds to wait for process to stop. Zero means unfinite wait.">; } let Definition = "platform" in {