summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorTodd Fiala <todd.fiala@gmail.com>2014-10-09 00:11:43 +0000
committerTodd Fiala <todd.fiala@gmail.com>2014-10-09 00:11:43 +0000
commit952bccd2128ea8322358d99b22d9ccc936b0b7a6 (patch)
treee1a0cd99ef57028481b64d42358d36576ab3d5ff /lldb/source
parent524002004db54bbc504c3286c6ee649ba441e2f4 (diff)
downloadbcm5719-llvm-952bccd2128ea8322358d99b22d9ccc936b0b7a6.tar.gz
bcm5719-llvm-952bccd2128ea8322358d99b22d9ccc936b0b7a6.zip
POSIX dynamic loader: add more logging around launch/attach, fix breakpoint handling on entry callback.
This change adds some logging around dynamic loader handling. It also fixes an issue where the dynamic loader entry breakpoint can end up being re-inserted, showing the wrong (i.e. software breakpoint) instruction at the stop location when a backtrace is displayed at program startup. I discussed with Jim Ingham a few weeks back. Essentially the one-hit breakpoints need to make it back to public state handling before the software breakpoint gets cleared. The flow I was hitting was that the breakpoint would get set, it would get hit, it would get cleared to step over, then it would get reapplied, when we never wanted it reapplied. Stops at the beginning of execution would then show backtraces with software breakpoint instructions in it, erroneously. This change fixes it. There might be a more elegant way to do this, or a flow change somewhere else to avoid, but it does fix an issue I experienced in startup breakpoint handling. llvm-svn: 219371
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp39
1 files changed, 37 insertions, 2 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 9b2d1349d07..79f20a89018 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -181,6 +181,10 @@ DynamicLoaderPOSIXDYLD::DidAttach()
void
DynamicLoaderPOSIXDYLD::DidLaunch()
{
+ Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ if (log)
+ log->Printf ("DynamicLoaderPOSIXDYLD::%s()", __FUNCTION__);
+
ModuleSP executable;
addr_t load_offset;
@@ -194,7 +198,11 @@ DynamicLoaderPOSIXDYLD::DidLaunch()
ModuleList module_list;
module_list.Append(executable);
UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, load_offset);
+
+ if (log)
+ log->Printf ("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", __FUNCTION__);
ProbeEntry();
+
m_process->GetTarget().ModulesDidLoad(module_list);
}
}
@@ -247,13 +255,15 @@ DynamicLoaderPOSIXDYLD::ProbeEntry()
}
if (log)
- if (log)
- log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " GetEntryPoint() returned address 0x%" PRIx64 ", setting entry breakpoint", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, entry);
+ log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " GetEntryPoint() returned address 0x%" PRIx64 ", setting entry breakpoint", __FUNCTION__, m_process ? m_process->GetID () : LLDB_INVALID_PROCESS_ID, entry);
Breakpoint *const entry_break = m_process->GetTarget().CreateBreakpoint(entry, true, false).get();
entry_break->SetCallback(EntryBreakpointHit, this, true);
entry_break->SetBreakpointKind("shared-library-event");
+
+ // Shoudn't hit this more than once.
+ entry_break->SetOneShot (true);
}
// The runtime linker has run and initialized the rendezvous structure once the
@@ -277,6 +287,31 @@ DynamicLoaderPOSIXDYLD::EntryBreakpointHit(void *baton,
if (log)
log->Printf ("DynamicLoaderPOSIXDYLD::%s called for pid %" PRIu64, __FUNCTION__, dyld_instance->m_process ? dyld_instance->m_process->GetID () : LLDB_INVALID_PROCESS_ID);
+ // Disable the breakpoint --- if a stop happens right after this, which we've seen on occasion, we don't
+ // want the breakpoint stepping thread-plan logic to show a breakpoint instruction at the disassembled
+ // entry point to the program. Disabling it prevents it. (One-shot is not enough - one-shot removal logic
+ // only happens after the breakpoint goes public, which wasn't happening in our scenario).
+ if (dyld_instance->m_process)
+ {
+ BreakpointSP breakpoint_sp = dyld_instance->m_process->GetTarget().GetBreakpointByID (break_id);
+ if (breakpoint_sp)
+ {
+ if (log)
+ log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " disabling breakpoint id %" PRIu64, __FUNCTION__, dyld_instance->m_process->GetID (), break_id);
+ breakpoint_sp->SetEnabled (false);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 " failed to find breakpoint for breakpoint id %" PRIu64, __FUNCTION__, dyld_instance->m_process->GetID (), break_id);
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("DynamicLoaderPOSIXDYLD::%s breakpoint id %" PRIu64 " no Process instance! Cannot disable breakpoint", __FUNCTION__, break_id);
+ }
+
dyld_instance->LoadAllCurrentModules();
dyld_instance->SetRendezvousBreakpoint();
return false; // Continue running.
OpenPOWER on IntegriCloud