mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-14 15:46:32 +00:00
This reapplies commit
232525f069
.
The original commit triggered a sanitizer failure when `Target` was
destroyed. In `Target::Destroy`, `DeleteCurrentProcess` was called, but
it did not destroy the thread creation breakpoints for the underlying
`ProcessGDBRemote` because `ProcessGDBRemote::Clear` was not called in
that path.
`Target `then proceeded to destroy its breakpoints, which resulted in a
call to the destructor of a `std::vector` containing the breakpoints.
Through a sequence of complicated events, destroying breakpoints caused
the reference count of the underlying `ProcessGDBRemote` to finally
reach zero. This, in turn, called `ProcessGDBRemote::Clear`, which
attempted to destroy the breakpoints. To do that, it would go back into
the Target's vector of breakpoints, which we are in the middle of
destroying.
We solve this by moving the breakpoint deletion into
`Process:DoDestroy`, which is a virtual Process method that will be
called much earlier.
This commit is contained in:
parent
38e64b1a84
commit
c2939b9bf6
@ -2571,9 +2571,18 @@ Status ProcessGDBRemote::DoDestroy() {
|
||||
|
||||
StopAsyncThread();
|
||||
KillDebugserverProcess();
|
||||
RemoveNewThreadBreakpoints();
|
||||
return Status();
|
||||
}
|
||||
|
||||
void ProcessGDBRemote::RemoveNewThreadBreakpoints() {
|
||||
if (m_thread_create_bp_sp) {
|
||||
if (TargetSP target_sp = m_target_wp.lock())
|
||||
target_sp->RemoveBreakpointByID(m_thread_create_bp_sp->GetID());
|
||||
m_thread_create_bp_sp.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessGDBRemote::SetLastStopPacket(
|
||||
const StringExtractorGDBRemote &response) {
|
||||
const bool did_exec =
|
||||
|
@ -436,6 +436,9 @@ private:
|
||||
lldb::user_id_t break_id,
|
||||
lldb::user_id_t break_loc_id);
|
||||
|
||||
/// Remove the breakpoints associated with thread creation from the Target.
|
||||
void RemoveNewThreadBreakpoints();
|
||||
|
||||
// ContinueDelegate interface
|
||||
void HandleAsyncStdout(llvm::StringRef out) override;
|
||||
void HandleAsyncMisc(llvm::StringRef data) override;
|
||||
|
@ -35,3 +35,23 @@ class TestInterruptThreadNames(TestBase):
|
||||
for bp in bps:
|
||||
num_resolved += bp.GetNumResolvedLocations()
|
||||
self.assertGreater(num_resolved, 0)
|
||||
|
||||
@skipUnlessDarwin
|
||||
def test_internal_bps_deleted_on_relaunch(self):
|
||||
self.build()
|
||||
|
||||
source_file = lldb.SBFileSpec("main.c")
|
||||
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
|
||||
self, "initial hello", source_file
|
||||
)
|
||||
|
||||
self.runCmd("break list --internal")
|
||||
output = self.res.GetOutput()
|
||||
self.assertEqual(output.count("thread-creation"), 1)
|
||||
|
||||
process.Kill()
|
||||
self.runCmd("run", RUN_SUCCEEDED)
|
||||
|
||||
self.runCmd("break list --internal")
|
||||
output = self.res.GetOutput()
|
||||
self.assertEqual(output.count("thread-creation"), 1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user