Create a Process::ModulesDidLoad() method to handle process-related tasks, as suggested by Jim Ingham. Make JITLoader instances use this to probe only new modules for relevant JIT symbols. Also re-enable the JITLoader hooks in Process.

llvm-svn: 203774
This commit is contained in:
Andrew MacPherson 2014-03-13 09:37:02 +00:00
parent 32956d651a
commit eb4d0607bf
8 changed files with 86 additions and 78 deletions

View File

@ -56,7 +56,7 @@ public:
//------------------------------------------------------------------
/// Called after attaching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after
/// Allow JITLoader plug-ins to execute some code after
/// attaching to a process.
//------------------------------------------------------------------
virtual void
@ -65,12 +65,19 @@ public:
//------------------------------------------------------------------
/// Called after launching a process.
///
/// Allow DynamicLoader plug-ins to execute some code after
/// Allow JITLoader plug-ins to execute some code after
/// the process has stopped for the first time on launch.
//------------------------------------------------------------------
virtual void
DidLaunch () = 0;
//------------------------------------------------------------------
/// Called after a new shared object has been loaded so that it can
/// be probed for JIT entry point hooks.
//------------------------------------------------------------------
virtual void
ModulesDidLoad (lldb_private::ModuleList &module_list) = 0;
protected:
//------------------------------------------------------------------
// Member variables.

View File

@ -47,6 +47,9 @@ public:
void
DidAttach();
void
ModulesDidLoad (ModuleList &module_list);
private:
std::vector<lldb::JITLoaderSP> m_jit_loaders_vec;
lldb_private::Mutex m_jit_loaders_mutex;

View File

@ -2575,6 +2575,9 @@ public:
void
SendAsyncInterrupt ();
void
ModulesDidLoad (ModuleList &module_list);
protected:
void

View File

@ -55,37 +55,43 @@ struct jit_descriptor
JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) :
JITLoader(process),
m_jit_objects(),
m_jit_break_id(LLDB_INVALID_BREAK_ID)
m_jit_break_id(LLDB_INVALID_BREAK_ID),
m_jit_descriptor_addr(LLDB_INVALID_ADDRESS)
{
m_notification_callbacks.baton = this;
m_notification_callbacks.initialize = nullptr;
m_notification_callbacks.process_state_changed =
ProcessStateChangedCallback;
m_process->RegisterNotificationCallbacks(m_notification_callbacks);
}
JITLoaderGDB::~JITLoaderGDB ()
{
if (LLDB_BREAK_ID_IS_VALID(m_jit_break_id))
m_process->GetTarget().RemoveBreakpointByID (m_jit_break_id);
m_jit_break_id = LLDB_INVALID_BREAK_ID;
}
void JITLoaderGDB::DidAttach()
{
SetJITBreakpoint();
Target &target = m_process->GetTarget();
ModuleList &module_list = target.GetImages();
SetJITBreakpoint(module_list);
}
void JITLoaderGDB::DidLaunch()
{
SetJITBreakpoint();
Target &target = m_process->GetTarget();
ModuleList &module_list = target.GetImages();
SetJITBreakpoint(module_list);
}
void
JITLoaderGDB::ModulesDidLoad(ModuleList &module_list)
{
if (!DidSetJITBreakpoint() && m_process->IsAlive())
SetJITBreakpoint(module_list);
}
//------------------------------------------------------------------
// Setup the JIT Breakpoint
//------------------------------------------------------------------
void
JITLoaderGDB::SetJITBreakpoint()
JITLoaderGDB::SetJITBreakpoint(lldb_private::ModuleList &module_list)
{
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
@ -96,11 +102,22 @@ JITLoaderGDB::SetJITBreakpoint()
log->Printf("JITLoaderGDB::%s looking for JIT register hook",
__FUNCTION__);
addr_t jit_addr = GetSymbolAddress(ConstString("__jit_debug_register_code"),
eSymbolTypeAny);
addr_t jit_addr = GetSymbolAddress(
module_list, ConstString("__jit_debug_register_code"), eSymbolTypeAny);
if (jit_addr == LLDB_INVALID_ADDRESS)
return;
m_jit_descriptor_addr = GetSymbolAddress(
module_list, ConstString("__jit_debug_descriptor"), eSymbolTypeData);
if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
{
if (log)
log->Printf(
"JITLoaderGDB::%s failed to find JIT descriptor address",
__FUNCTION__);
return;
}
if (log)
log->Printf("JITLoaderGDB::%s setting JIT breakpoint",
__FUNCTION__);
@ -130,26 +147,18 @@ JITLoaderGDB::JITDebugBreakpointHit(void *baton,
bool
JITLoaderGDB::ReadJITDescriptor(bool all_entries)
{
if (m_jit_descriptor_addr == LLDB_INVALID_ADDRESS)
return false;
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER));
Target &target = m_process->GetTarget();
ModuleList &images = target.GetImages();
addr_t jit_addr = GetSymbolAddress(ConstString("__jit_debug_descriptor"),
eSymbolTypeData);
if (jit_addr == LLDB_INVALID_ADDRESS)
{
if (log)
log->Printf(
"JITLoaderGDB::%s failed to find JIT descriptor address",
__FUNCTION__);
return false;
}
ModuleList &module_list = target.GetImages();
jit_descriptor jit_desc;
const size_t jit_desc_size = sizeof(jit_desc);
Error error;
size_t bytes_read =
m_process->DoReadMemory(jit_addr, &jit_desc, jit_desc_size, error);
size_t bytes_read = m_process->DoReadMemory(
m_jit_descriptor_addr, &jit_desc, jit_desc_size, error);
if (bytes_read != jit_desc_size || !error.Success())
{
if (log)
@ -208,7 +217,7 @@ JITLoaderGDB::ReadJITDescriptor(bool all_entries)
// load the symbol table right away
module_sp->GetObjectFile()->GetSymtab();
images.AppendIfNeeded(module_sp);
module_list.AppendIfNeeded(module_sp);
ModuleList module_list;
module_list.Append(module_sp);
@ -250,7 +259,7 @@ JITLoaderGDB::ReadJITDescriptor(bool all_entries)
}
}
}
images.Remove(module_sp);
module_list.Remove(module_sp);
m_jit_objects.erase(it);
}
}
@ -327,48 +336,15 @@ JITLoaderGDB::DidSetJITBreakpoint() const
return LLDB_BREAK_ID_IS_VALID(m_jit_break_id);
}
void
JITLoaderGDB::ProcessStateChangedCallback(void *baton,
lldb_private::Process *process,
lldb::StateType state)
{
JITLoaderGDB* instance = static_cast<JITLoaderGDB*>(baton);
switch (state)
{
case eStateConnected:
case eStateAttaching:
case eStateLaunching:
case eStateInvalid:
case eStateUnloaded:
case eStateExited:
case eStateDetached:
// instance->Clear(false);
break;
case eStateRunning:
case eStateStopped:
// Keep trying to set our JIT breakpoint each time we stop until we
// succeed
if (!instance->DidSetJITBreakpoint() && process->IsAlive())
instance->SetJITBreakpoint();
break;
case eStateStepping:
case eStateCrashed:
case eStateSuspended:
break;
}
}
addr_t
JITLoaderGDB::GetSymbolAddress(const ConstString &name, SymbolType symbol_type) const
JITLoaderGDB::GetSymbolAddress(ModuleList &module_list, const ConstString &name,
SymbolType symbol_type) const
{
SymbolContextList target_symbols;
Target &target = m_process->GetTarget();
ModuleList &images = target.GetImages();
if (!images.FindSymbolsWithNameAndType(name, symbol_type, target_symbols))
if (!module_list.FindSymbolsWithNameAndType(name, symbol_type,
target_symbols))
return LLDB_INVALID_ADDRESS;
SymbolContext sym_ctx;

View File

@ -63,13 +63,17 @@ public:
virtual void
DidLaunch ();
virtual void
ModulesDidLoad (lldb_private::ModuleList &module_list);
private:
lldb::addr_t
GetSymbolAddress(const lldb_private::ConstString &name,
GetSymbolAddress(lldb_private::ModuleList &module_list,
const lldb_private::ConstString &name,
lldb::SymbolType symbol_type) const;
void
SetJITBreakpoint();
SetJITBreakpoint(lldb_private::ModuleList &module_list);
bool
DidSetJITBreakpoint() const;
@ -93,7 +97,7 @@ private:
JITObjectMap m_jit_objects;
lldb::user_id_t m_jit_break_id;
lldb_private::Process::Notifications m_notification_callbacks;
lldb::addr_t m_jit_descriptor_addr;
};

View File

@ -67,3 +67,11 @@ JITLoaderList::DidAttach()
for (auto const &jit_loader : m_jit_loaders_vec)
jit_loader->DidAttach();
}
void
JITLoaderList::ModulesDidLoad(ModuleList &module_list)
{
Mutex::Locker locker(m_jit_loaders_mutex);
for (auto const &jit_loader : m_jit_loaders_vec)
jit_loader->ModulesDidLoad(module_list);
}

View File

@ -3068,7 +3068,7 @@ Process::Launch (ProcessLaunchInfo &launch_info)
if (dyld)
dyld->DidLaunch();
// GetJITLoaders().DidLaunch();
GetJITLoaders().DidLaunch();
SystemRuntime *system_runtime = GetSystemRuntime ();
if (system_runtime)
@ -3117,7 +3117,7 @@ Process::LoadCore ()
if (dyld)
dyld->DidAttach();
//GetJITLoaders().DidAttach();
GetJITLoaders().DidAttach();
SystemRuntime *system_runtime = GetSystemRuntime ();
if (system_runtime)
@ -3396,7 +3396,7 @@ Process::CompleteAttach ()
if (dyld)
dyld->DidAttach();
// GetJITLoaders().DidAttach();
GetJITLoaders().DidAttach();
SystemRuntime *system_runtime = GetSystemRuntime ();
if (system_runtime)
@ -6052,3 +6052,14 @@ Process::ResolveIndirectFunction(const Address *address, Error &error)
return function_addr;
}
void
Process::ModulesDidLoad (ModuleList &module_list)
{
SystemRuntime *sys_runtime = GetSystemRuntime();
if (sys_runtime)
{
sys_runtime->ModulesDidLoad (module_list);
}
GetJITLoaders().ModulesDidLoad (module_list);
}

View File

@ -1172,11 +1172,7 @@ Target::ModulesDidLoad (ModuleList &module_list)
m_breakpoint_list.UpdateBreakpoints (module_list, true, false);
if (m_process_sp)
{
SystemRuntime *sys_runtime = m_process_sp->GetSystemRuntime();
if (sys_runtime)
{
sys_runtime->ModulesDidLoad (module_list);
}
m_process_sp->ModulesDidLoad (module_list);
}
// TODO: make event data that packages up the module_list
BroadcastEvent (eBroadcastBitModulesLoaded, NULL);