forked from OSchip/llvm-project
Fix a crasher that could happen when you run LLDB and evaluate an expression where the objective C runtime registers a helper function, and also have an Objective C or C++ exception breakpoint. When shutting down the process in Process::Finalize() we clear a STL collection class and that causes objects to be destroyed that could re-enter Process and cause it to try to iterate over that same collection class that is being destroyed.
Guard against this by setting a new "m_finalizing" flag that lets us know we are in the process of finalizing. <rdar://problem/20369152> llvm-svn: 233935
This commit is contained in:
parent
b0a650aca2
commit
c00ca313fd
|
@ -3171,7 +3171,8 @@ protected:
|
||||||
ArchSpec::StopInfoOverrideCallbackType m_stop_info_override_callback;
|
ArchSpec::StopInfoOverrideCallbackType m_stop_info_override_callback;
|
||||||
bool m_currently_handling_do_on_removals;
|
bool m_currently_handling_do_on_removals;
|
||||||
bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check.
|
bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check.
|
||||||
bool m_finalize_called;
|
bool m_finalizing; // This is set at the beginning of Process::Finalize() to stop functions from looking up or creating things during a finalize call
|
||||||
|
bool m_finalize_called; // This is set at the end of Process::Finalize()
|
||||||
bool m_clear_thread_plans_on_stop;
|
bool m_clear_thread_plans_on_stop;
|
||||||
bool m_force_next_event_delivery;
|
bool m_force_next_event_delivery;
|
||||||
lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent.
|
lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent.
|
||||||
|
|
|
@ -749,9 +749,10 @@ Process::Process(Target &target, Listener &listener, const UnixSignalsSP &unix_s
|
||||||
m_private_run_lock (),
|
m_private_run_lock (),
|
||||||
m_currently_handling_event(false),
|
m_currently_handling_event(false),
|
||||||
m_stop_info_override_callback (NULL),
|
m_stop_info_override_callback (NULL),
|
||||||
m_finalize_called(false),
|
m_finalizing (false),
|
||||||
|
m_finalize_called (false),
|
||||||
m_clear_thread_plans_on_stop (false),
|
m_clear_thread_plans_on_stop (false),
|
||||||
m_force_next_event_delivery(false),
|
m_force_next_event_delivery (false),
|
||||||
m_last_broadcast_state (eStateInvalid),
|
m_last_broadcast_state (eStateInvalid),
|
||||||
m_destroy_in_process (false),
|
m_destroy_in_process (false),
|
||||||
m_can_jit(eCanJITDontKnow)
|
m_can_jit(eCanJITDontKnow)
|
||||||
|
@ -822,6 +823,8 @@ Process::GetGlobalProperties()
|
||||||
void
|
void
|
||||||
Process::Finalize()
|
Process::Finalize()
|
||||||
{
|
{
|
||||||
|
m_finalizing = true;
|
||||||
|
|
||||||
// Destroy this process if needed
|
// Destroy this process if needed
|
||||||
switch (GetPrivateState())
|
switch (GetPrivateState())
|
||||||
{
|
{
|
||||||
|
@ -1832,6 +1835,12 @@ Process::GetImageInfoAddress()
|
||||||
uint32_t
|
uint32_t
|
||||||
Process::LoadImage (const FileSpec &image_spec, Error &error)
|
Process::LoadImage (const FileSpec &image_spec, Error &error)
|
||||||
{
|
{
|
||||||
|
if (m_finalizing)
|
||||||
|
{
|
||||||
|
error.SetErrorString("process is tearing itself down");
|
||||||
|
return LLDB_INVALID_IMAGE_TOKEN;
|
||||||
|
}
|
||||||
|
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
image_spec.GetPath(path, sizeof(path));
|
image_spec.GetPath(path, sizeof(path));
|
||||||
|
|
||||||
|
@ -1951,6 +1960,13 @@ Error
|
||||||
Process::UnloadImage (uint32_t image_token)
|
Process::UnloadImage (uint32_t image_token)
|
||||||
{
|
{
|
||||||
Error error;
|
Error error;
|
||||||
|
|
||||||
|
if (m_finalizing)
|
||||||
|
{
|
||||||
|
error.SetErrorString("process is tearing itself down");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
if (image_token < m_image_tokens.size())
|
if (image_token < m_image_tokens.size())
|
||||||
{
|
{
|
||||||
const addr_t image_addr = m_image_tokens[image_token];
|
const addr_t image_addr = m_image_tokens[image_token];
|
||||||
|
@ -2025,6 +2041,9 @@ Process::UnloadImage (uint32_t image_token)
|
||||||
const lldb::ABISP &
|
const lldb::ABISP &
|
||||||
Process::GetABI()
|
Process::GetABI()
|
||||||
{
|
{
|
||||||
|
if (m_finalizing)
|
||||||
|
return lldb::ABISP();
|
||||||
|
|
||||||
if (!m_abi_sp)
|
if (!m_abi_sp)
|
||||||
m_abi_sp = ABI::FindPlugin(m_target.GetArchitecture());
|
m_abi_sp = ABI::FindPlugin(m_target.GetArchitecture());
|
||||||
return m_abi_sp;
|
return m_abi_sp;
|
||||||
|
@ -2033,6 +2052,9 @@ Process::GetABI()
|
||||||
LanguageRuntime *
|
LanguageRuntime *
|
||||||
Process::GetLanguageRuntime(lldb::LanguageType language, bool retry_if_null)
|
Process::GetLanguageRuntime(lldb::LanguageType language, bool retry_if_null)
|
||||||
{
|
{
|
||||||
|
if (m_finalizing)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
LanguageRuntimeCollection::iterator pos;
|
LanguageRuntimeCollection::iterator pos;
|
||||||
pos = m_language_runtimes.find (language);
|
pos = m_language_runtimes.find (language);
|
||||||
if (pos == m_language_runtimes.end() || (retry_if_null && !(*pos).second))
|
if (pos == m_language_runtimes.end() || (retry_if_null && !(*pos).second))
|
||||||
|
@ -2067,6 +2089,9 @@ Process::GetObjCLanguageRuntime (bool retry_if_null)
|
||||||
bool
|
bool
|
||||||
Process::IsPossibleDynamicValue (ValueObject& in_value)
|
Process::IsPossibleDynamicValue (ValueObject& in_value)
|
||||||
{
|
{
|
||||||
|
if (m_finalizing)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (in_value.IsDynamic())
|
if (in_value.IsDynamic())
|
||||||
return false;
|
return false;
|
||||||
LanguageType known_type = in_value.GetObjectRuntimeLanguage();
|
LanguageType known_type = in_value.GetObjectRuntimeLanguage();
|
||||||
|
|
Loading…
Reference in New Issue