forked from OSchip/llvm-project
Did some cleanup to stop us from leaking Pipe file descriptors.
The main issue was the Communication::Disconnect() was calling its Connection::Disconnect() but this wouldn't release the pipes that the ConnectionFileDescriptor was using. We also have someone that is holding a strong reference to the Process so that when you re-run, target replaces its m_process_sp, but it doesn't get destructed because someone has a strong reference to it. I need to track that down. But, even if we have a strong reference to the a process that is outstanding, we need to call Process::Finalize() to have it release as much of its resources as possible to avoid memory bloat. Removed the ProcessGDBRemote::SetExitStatus() override and replaced it with ProcessGDBRemote::DidExit(). Now we aren't leaking file descriptors and the stand alone test suite should run much better. llvm-svn: 238089
This commit is contained in:
parent
ac60f4594f
commit
5df78fa35b
|
@ -372,6 +372,9 @@ ConnectionFileDescriptor::Disconnect(Error *error_ptr)
|
||||||
if (error_ptr)
|
if (error_ptr)
|
||||||
*error_ptr = error.Fail() ? error : error2;
|
*error_ptr = error.Fail() ? error : error2;
|
||||||
|
|
||||||
|
// Close any pipes we were using for async interrupts
|
||||||
|
m_pipe.Close();
|
||||||
|
|
||||||
m_uri.clear();
|
m_uri.clear();
|
||||||
m_shutting_down = false;
|
m_shutting_down = false;
|
||||||
return status;
|
return status;
|
||||||
|
|
|
@ -1401,12 +1401,11 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, const Pro
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
bool
|
ProcessGDBRemote::DidExit ()
|
||||||
ProcessGDBRemote::SetExitStatus (int exit_status, const char *cstr)
|
|
||||||
{
|
{
|
||||||
|
// When we exit, disconnect from the GDB server communications
|
||||||
m_gdb_comm.Disconnect();
|
m_gdb_comm.Disconnect();
|
||||||
return Process::SetExitStatus (exit_status, cstr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -225,10 +225,10 @@ public:
|
||||||
SendEventData(const char *data) override;
|
SendEventData(const char *data) override;
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Override SetExitStatus so we can disconnect from the remote GDB server
|
// Override DidExit so we can disconnect from the remote GDB server
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
bool
|
void
|
||||||
SetExitStatus (int exit_status, const char *cstr) override;
|
DidExit () override;
|
||||||
|
|
||||||
void
|
void
|
||||||
SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max);
|
SetUserSpecifiedMaxMemoryTransferSize (uint64_t user_specified_max);
|
||||||
|
|
|
@ -1466,9 +1466,24 @@ Process::SetExitStatus (int status, const char *cstr)
|
||||||
m_exit_string.clear();
|
m_exit_string.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
DidExit ();
|
// When we exit, we no longer need to the communication channel
|
||||||
|
m_stdio_communication.StopReadThread();
|
||||||
|
m_stdio_communication.Disconnect();
|
||||||
|
m_stdin_forward = false;
|
||||||
|
|
||||||
|
// And we don't need the input reader anymore as well
|
||||||
|
if (m_process_input_reader)
|
||||||
|
{
|
||||||
|
m_process_input_reader->SetIsDone(true);
|
||||||
|
m_process_input_reader->Cancel();
|
||||||
|
m_process_input_reader.reset();
|
||||||
|
}
|
||||||
|
|
||||||
SetPrivateState (eStateExited);
|
SetPrivateState (eStateExited);
|
||||||
|
|
||||||
|
// Allow subclasses to do some cleanup
|
||||||
|
DidExit ();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2580,10 +2580,24 @@ Target::Launch (ProcessLaunchInfo &launch_info, Stream *stream)
|
||||||
if (log)
|
if (log)
|
||||||
log->Printf ("Target::%s asking the platform to debug the process", __FUNCTION__);
|
log->Printf ("Target::%s asking the platform to debug the process", __FUNCTION__);
|
||||||
|
|
||||||
|
// Get a weak pointer to the previous process if we have one
|
||||||
|
ProcessWP process_wp;
|
||||||
|
if (m_process_sp)
|
||||||
|
process_wp = m_process_sp;
|
||||||
m_process_sp = GetPlatform()->DebugProcess (launch_info,
|
m_process_sp = GetPlatform()->DebugProcess (launch_info,
|
||||||
debugger,
|
debugger,
|
||||||
this,
|
this,
|
||||||
error);
|
error);
|
||||||
|
|
||||||
|
// Cleanup the old process since someone might still have a strong
|
||||||
|
// reference to this process and we would like to allow it to cleanup
|
||||||
|
// as much as it can without the object being destroyed. We try to
|
||||||
|
// lock the shared pointer and if that works, then someone else still
|
||||||
|
// has a strong reference to the process.
|
||||||
|
|
||||||
|
ProcessSP old_process_sp(process_wp.lock());
|
||||||
|
if (old_process_sp)
|
||||||
|
old_process_sp->Finalize();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue