Use the dyld_mode, image_infos & image_infos_count passed into the shared library notification function

to update libraries rather than reading the whole all_imaage_infos structure every time we get notified.

llvm-svn: 133448
This commit is contained in:
Jim Ingham 2011-06-20 17:32:44 +00:00
parent e8ae1db4d8
commit f72ce3a216
9 changed files with 416 additions and 233 deletions

View File

@ -91,6 +91,8 @@ public:
//------------------------------------------------------------------
virtual void
DidLaunch () = 0;
//------------------------------------------------------------------
/// Get whether the process should stop when images change.

View File

@ -3292,7 +3292,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
@ -3324,7 +3324,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PREPROCESSOR_DEFINITIONS = (
__STDC_CONSTANT_MACROS,
@ -3616,7 +3616,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PREPROCESSOR_DEFINITIONS = (
__STDC_CONSTANT_MACROS,

View File

@ -597,9 +597,9 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
Error error;
ExecutionResults execution_results = eExecutionSetupError;
if (exe_ctx.process == NULL)
if (exe_ctx.process == NULL || exe_ctx.process->GetState() != lldb::eStateStopped)
{
error.SetErrorString ("Must have a process to evaluate expressions.");
error.SetErrorString ("Must have a live but stopped process to evaluate expressions.");
result_valobj_sp = ValueObjectConstResult::Create (NULL, error);
return eExecutionSetupError;

View File

@ -288,7 +288,7 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::
}
// Update all image infos
UpdateAllImageInfos();
InitializeFromAllImageInfos ();
// If we didn't have an executable before, but now we do, then the
// dyld module shared pointer might be unique and we may need to add
@ -442,11 +442,79 @@ DynamicLoaderMacOSXDYLD::UnloadImageLoadAddress (Module *module, DYLDImageInfo&
// or not (based on global preference).
//----------------------------------------------------------------------
bool
DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
DynamicLoaderMacOSXDYLD::NotifyBreakpointHit (void *baton,
StoppointCallbackContext *context,
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id)
{
// Let the event know that the images have changed
// DYLD passes three arguments to the notification breakpoint.
// Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
// Arg2: uint32_t infoCount - Number of shared libraries added
// Arg3: dyld_image_info info[] - Array of structs of the form:
// const struct mach_header *imageLoadAddress
// const char *imageFilePath
// uintptr_t imageFileModDate (a time_t)
DynamicLoaderMacOSXDYLD* dyld_instance = (DynamicLoaderMacOSXDYLD*) baton;
dyld_instance->UpdateAllImageInfos();
// First step is to see if we've already initialized the all image infos. If we haven't then this function
// will do so and return true. In the course of initializing the all_image_infos it will read the complete
// current state, so we don't need to figure out what has changed from the data passed in to us.
if (dyld_instance->InitializeFromAllImageInfos())
return dyld_instance->GetStopWhenImagesChange();
Process *process = context->exe_ctx.process;
const lldb::ABISP &abi = process->GetABI();
if (abi != NULL)
{
// Build up the value array to store the three arguments given above, then get the values from the ABI:
ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
ValueList argument_values;
Value input_value;
void *clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
void *clang_uint32_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, 32);
input_value.SetValueType (Value::eValueTypeScalar);
input_value.SetContext (Value::eContextTypeClangType, clang_uint32_type);
argument_values.PushValue(input_value);
argument_values.PushValue(input_value);
input_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
argument_values.PushValue (input_value);
if (abi->GetArgumentValues (*context->exe_ctx.thread, argument_values))
{
uint32_t dyld_mode = argument_values.GetValueAtIndex(0)->GetScalar().UInt (-1);
if (dyld_mode != -1)
{
// Okay the mode was right, now get the number of elements, and the array of new elements...
uint32_t image_infos_count = argument_values.GetValueAtIndex(1)->GetScalar().UInt (-1);
if (image_infos_count != -1)
{
// Got the number added, now go through the array of added elements, putting out the mach header
// address, and adding the image.
// Note, I'm not putting in logging here, since the AddModules & RemoveModules functions do
// all the logging internally.
lldb::addr_t image_infos_addr = argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
if (dyld_mode == 0)
{
// This is add:
dyld_instance->AddModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
}
else
{
// This is remove:
dyld_instance->RemoveModulesUsingImageInfosAddress (image_infos_addr, image_infos_count);
}
}
}
}
}
// Return true to stop the target, false to just let the target run
return dyld_instance->GetStopWhenImagesChange();
}
@ -571,229 +639,297 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInfosStructure ()
return false;
}
bool
DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
{
DYLDImageInfo::collection image_infos;
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
log->Printf ("Adding %d modules.\n");
Mutex::Locker locker(m_mutex);
if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
return true;
if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
return false;
UpdateImageInfosHeaderAndLoadCommands (image_infos, image_infos_count, false);
bool return_value = AddModulesUsingImageInfos (image_infos);
m_dyld_image_infos_stop_id = m_process->GetStopID();
return return_value;
}
// Adds the modules in image_infos to m_dyld_image_infos.
// NB don't call this passing in m_dyld_image_infos.
bool
DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos)
{
// Now add these images to the main list.
ModuleList loaded_module_list;
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
{
if (log)
{
log->Printf ("Adding new image at address=0x%16.16llx.", image_infos[idx].address);
image_infos[idx].PutToLog (log.get());
}
m_dyld_image_infos.push_back(image_infos[idx]);
ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], true, NULL));
if (image_module_sp)
{
if (image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
image_module_sp->SetIsDynamicLinkEditor (true);
ObjectFile *objfile = image_module_sp->GetObjectFile ();
if (objfile)
{
SectionList *sections = objfile->GetSectionList();
if (sections)
{
ConstString commpage_dbstr("__commpage");
Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
if (commpage_section)
{
ModuleList& target_images = m_process->GetTarget().GetImages();
const FileSpec objfile_file_spec = objfile->GetFileSpec();
ArchSpec arch (image_infos[idx].GetArchitecture ());
ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec,
&arch,
&commpage_dbstr));
if (!commpage_image_module_sp)
{
commpage_image_module_sp
= m_process->GetTarget().GetSharedModule (image_infos[idx].file_spec,
arch,
NULL,
&commpage_dbstr,
objfile->GetOffset() + commpage_section->GetFileOffset());
}
if (commpage_image_module_sp)
UpdateCommPageLoadAddress (commpage_image_module_sp.get());
}
}
}
// UpdateImageLoadAddress will return true if any segments
// change load address. We need to check this so we don't
// mention that all loaded shared libraries are newly loaded
// each time we hit out dyld breakpoint since dyld will list all
// shared libraries each time.
if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
{
loaded_module_list.AppendIfNeeded (image_module_sp);
}
}
}
if (loaded_module_list.GetSize() > 0)
{
// FIXME: This should really be in the Runtime handlers class, which should get
// called by the target's ModulesDidLoad, but we're doing it all locally for now
// to save time.
// Also, I'm assuming there can be only one libobjc dylib loaded...
ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
{
size_t num_modules = loaded_module_list.GetSize();
for (int i = 0; i < num_modules; i++)
{
if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
{
objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
break;
}
}
}
if (log)
loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
m_process->GetTarget().ModulesDidLoad (loaded_module_list);
}
return true;
}
bool
DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
{
DYLDImageInfo::collection image_infos;
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Mutex::Locker locker(m_mutex);
if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
return true;
// First read in the image_infos for the removed modules, and their headers & load commands.
if (!ReadImageInfos (image_infos_addr, image_infos_count, image_infos))
{
if (log)
log->PutCString ("Failed reading image infos array.");
return false;
}
if (log)
log->Printf ("Removing %d modules.", image_infos_count);
ModuleList unloaded_module_list;
for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
{
if (log)
{
log->Printf ("Removing module at address=0x%16.16llx.", image_infos[idx].address);
image_infos[idx].PutToLog (log.get());
}
// Remove this image_infos from the m_all_image_infos. We do the comparision by address
// rather than by file spec because we can have many modules with the same "file spec" in the
// case that they are modules loaded from memory.
//
// Also copy over the uuid from the old entry to the removed entry so we can
// use it to lookup the module in the module list.
DYLDImageInfo::collection::iterator pos, end = m_dyld_image_infos.end();
for (pos = m_dyld_image_infos.begin(); pos != end; pos++)
{
if (image_infos[idx].address == (*pos).address)
{
image_infos[idx].uuid = (*pos).uuid;
// Add the module from this image_info to the "unloaded_module_list". We'll remove them all at
// one go later on.
ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[idx], false, NULL));
if (unload_image_module_sp.get())
{
UnloadImageLoadAddress (unload_image_module_sp.get(), image_infos[idx]);
unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
}
else
{
if (log)
{
log->Printf ("Could not find module for unloading info entry:");
image_infos[idx].PutToLog(log.get());
}
}
// Then remove it from the m_dyld_image_infos:
m_dyld_image_infos.erase(pos);
break;
}
}
if (pos == end)
{
if (log)
{
log->Printf ("Could not find image_info entry for unloading image:");
image_infos[idx].PutToLog(log.get());
}
}
}
if (unloaded_module_list.GetSize() > 0)
{
if (log)
{
log->PutCString("Unloaded:");
unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
}
m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
}
m_dyld_image_infos_stop_id = m_process->GetStopID();
return true;
}
bool
DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr,
uint32_t image_infos_count,
DYLDImageInfo::collection &image_infos)
{
const ByteOrder endian = m_dyld.GetByteOrder();
const uint32_t addr_size = m_dyld.GetAddressByteSize();
image_infos.resize(image_infos_count);
const size_t count = image_infos.size() * 3 * addr_size;
DataBufferHeap info_data(count, 0);
Error error;
const size_t bytes_read = m_process->ReadMemory (image_infos_addr,
info_data.GetBytes(),
info_data.GetByteSize(),
error);
if (bytes_read == count)
{
uint32_t info_data_offset = 0;
DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
for (int i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
{
image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
char raw_path[PATH_MAX];
m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path));
// don't resolve the path
const bool resolve_path = false;
image_infos[i].file_spec.SetFile(raw_path, resolve_path);
}
return true;
}
else
{
return false;
}
}
//----------------------------------------------------------------------
// If we have found where the "_dyld_all_image_infos" lives in memory,
// read the current info from it, and then update all image load
// addresses (or lack thereof).
// addresses (or lack thereof). Only do this if this is the first time
// we're reading the dyld infos. Return true if we actually read anything,
// and false otherwise.
//----------------------------------------------------------------------
uint32_t
DynamicLoaderMacOSXDYLD::UpdateAllImageInfos()
bool
DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
{
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
ModuleList& target_images = m_process->GetTarget().GetImages();
Mutex::Locker locker(m_mutex);
if (m_process->GetStopID() == m_dyld_image_infos_stop_id
|| m_dyld_image_infos.size() != 0)
return false;
if (ReadAllImageInfosStructure ())
{
Mutex::Locker locker(m_mutex);
if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
m_dyld_image_infos.size();
uint32_t idx;
uint32_t i = 0;
// Since we can't downsize a vector, we must do this using the swap method
DYLDImageInfo::collection old_dyld_all_image_infos;
old_dyld_all_image_infos.swap(m_dyld_image_infos);
// If we made it here, we are assuming that the all dylib info data should
// be valid, lets read the info array.
const ByteOrder endian = m_dyld.GetByteOrder();
const uint32_t addr_size = m_dyld.GetAddressByteSize();
if (m_dyld_all_image_infos.dylib_info_count > 0)
{
if (m_dyld_all_image_infos.dylib_info_addr == 0)
{
// DYLD is updating the images right now...
// DYLD is updating the images now. So we should say we have no images, and then we'll
// figure it out when we hit the added breakpoint.
return false;
}
else
{
m_dyld_image_infos.resize(m_dyld_all_image_infos.dylib_info_count);
const size_t count = m_dyld_image_infos.size() * 3 * addr_size;
DataBufferHeap info_data(count, 0);
Error error;
const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos.dylib_info_addr,
info_data.GetBytes(),
info_data.GetByteSize(),
error);
if (bytes_read == count)
{
uint32_t info_data_offset = 0;
DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
for (i = 0; i < m_dyld_image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
{
m_dyld_image_infos[i].address = info_data_ref.GetPointer(&info_data_offset);
lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset);
m_dyld_image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset);
char raw_path[PATH_MAX];
m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path));
// don't resolve the path
const bool resolve_path = false;
m_dyld_image_infos[i].file_spec.SetFile(raw_path, resolve_path);
}
UpdateAllImageInfosHeaderAndLoadCommands();
}
else
if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr,
m_dyld_all_image_infos.dylib_info_count))
{
DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
m_dyld_image_infos.clear();
}
}
}
// If our new list is smaller than our old list, we have unloaded
// some shared libraries
if (m_dyld_image_infos.size() != old_dyld_all_image_infos.size())
{
ModuleList unloaded_module_list;
if (old_dyld_all_image_infos.size() == 0)
{
// This is the first time we are loading shared libraries,
// we need to make sure to trim anything that isn't in the
// m_dyld_image_infos out of the target module list since
// we might have shared libraries that got loaded from
// elsewhere due to DYLD_FRAMEWORK_PATH, or DYLD_LIBRARY_PATH
// environment variables...
const size_t num_images = target_images.GetSize();
for (idx = 0; idx < num_images; ++idx)
{
ModuleSP module_sp (target_images.GetModuleAtIndex (idx));
if (GetImageInfo (module_sp.get()) == NULL)
unloaded_module_list.AppendIfNeeded (module_sp);
}
}
else
{
uint32_t old_idx;
for (idx = 0; idx < old_dyld_all_image_infos.size(); ++idx)
{
for (old_idx = idx; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
{
if (m_dyld_image_infos[idx].file_spec == old_dyld_all_image_infos[old_idx].file_spec)
{
old_dyld_all_image_infos[old_idx].address = LLDB_INVALID_ADDRESS;
break;
}
}
}
for (old_idx = 0; old_idx < old_dyld_all_image_infos.size(); ++old_idx)
{
if (old_dyld_all_image_infos[old_idx].address != LLDB_INVALID_ADDRESS)
{
if (log)
old_dyld_all_image_infos[old_idx].PutToLog (log.get());
ModuleSP unload_image_module_sp (FindTargetModuleForDYLDImageInfo (old_dyld_all_image_infos[old_idx], false, NULL));
if (unload_image_module_sp.get())
{
if (UnloadImageLoadAddress (unload_image_module_sp.get(), old_dyld_all_image_infos[old_idx]))
unloaded_module_list.AppendIfNeeded (unload_image_module_sp);
}
}
}
}
if (unloaded_module_list.GetSize() > 0)
{
if (log)
{
log->PutCString("Unloaded:");
unloaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidUnload");
}
m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
}
}
else
{
if (log)
PutToLog(log.get());
}
m_dyld_image_infos_stop_id = m_process->GetStopID();
return true;
}
else
{
m_dyld_image_infos.clear();
}
const uint32_t num_dylibs = m_dyld_image_infos.size();
if (num_dylibs > 0)
{
ModuleList loaded_module_list;
for (uint32_t idx = 0; idx<num_dylibs; ++idx)
{
ModuleSP image_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[idx], true, NULL));
if (image_module_sp)
{
if (m_dyld_image_infos[idx].header.filetype == llvm::MachO::HeaderFileTypeDynamicLinkEditor)
image_module_sp->SetIsDynamicLinkEditor (true);
ObjectFile *objfile = image_module_sp->GetObjectFile ();
if (objfile)
{
SectionList *sections = objfile->GetSectionList();
if (sections)
{
ConstString commpage_dbstr("__commpage");
Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
if (commpage_section)
{
const FileSpec objfile_file_spec = objfile->GetFileSpec();
ArchSpec arch (m_dyld_image_infos[idx].GetArchitecture ());
ModuleSP commpage_image_module_sp(target_images.FindFirstModuleForFileSpec (objfile_file_spec, &arch, &commpage_dbstr));
if (!commpage_image_module_sp)
{
commpage_image_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[idx].file_spec,
arch,
NULL,
&commpage_dbstr,
objfile->GetOffset() + commpage_section->GetFileOffset());
}
if (commpage_image_module_sp)
UpdateCommPageLoadAddress (commpage_image_module_sp.get());
}
}
}
// UpdateImageLoadAddress will return true if any segments
// change load address. We need to check this so we don't
// mention that all loaded shared libraries are newly loaded
// each time we hit out dyld breakpoint since dyld will list all
// shared libraries each time.
if (UpdateImageLoadAddress (image_module_sp.get(), m_dyld_image_infos[idx]))
{
loaded_module_list.AppendIfNeeded (image_module_sp);
}
}
}
if (loaded_module_list.GetSize() > 0)
{
// FIXME: This should really be in the Runtime handlers class, which should get
// called by the target's ModulesDidLoad, but we're doing it all locally for now
// to save time.
// Also, I'm assuming there can be only one libobjc dylib loaded...
ObjCLanguageRuntime *objc_runtime = m_process->GetObjCLanguageRuntime();
if (objc_runtime != NULL && !objc_runtime->HasReadObjCLibrary())
{
size_t num_modules = loaded_module_list.GetSize();
for (int i = 0; i < num_modules; i++)
{
if (objc_runtime->IsModuleObjCLibrary (loaded_module_list.GetModuleAtIndex (i)))
{
objc_runtime->ReadObjCLibrary (loaded_module_list.GetModuleAtIndex (i));
break;
}
}
}
if (log)
loaded_module_list.LogUUIDAndPaths (log, "DynamicLoaderMacOSXDYLD::ModulesDidLoad");
m_process->GetTarget().ModulesDidLoad (loaded_module_list);
}
}
return m_dyld_image_infos.size();
return false;
}
//----------------------------------------------------------------------
@ -968,40 +1104,41 @@ DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImage
// Read the mach_header and load commands for each image that the
// _dyld_all_image_infos structure points to and cache the results.
//----------------------------------------------------------------------
void
DynamicLoaderMacOSXDYLD::UpdateAllImageInfosHeaderAndLoadCommands()
DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos,
uint32_t infos_count,
bool update_executable)
{
uint32_t exe_idx = UINT32_MAX;
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
// Read any UUID values that we can get
for (uint32_t i = 0; i < m_dyld_all_image_infos.dylib_info_count; i++)
for (uint32_t i = 0; i < infos_count; i++)
{
if (!m_dyld_image_infos[i].UUIDValid())
if (!image_infos[i].UUIDValid())
{
DataExtractor data; // Load command data
if (!ReadMachHeader (m_dyld_image_infos[i].address, &m_dyld_image_infos[i].header, &data))
if (!ReadMachHeader (image_infos[i].address, &image_infos[i].header, &data))
continue;
ParseLoadCommands (data, m_dyld_image_infos[i], NULL);
ParseLoadCommands (data, image_infos[i], NULL);
if (m_dyld_image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
if (image_infos[i].header.filetype == llvm::MachO::HeaderFileTypeExecutable)
exe_idx = i;
if (log)
m_dyld_image_infos[i].PutToLog (log.get());
}
}
if (exe_idx < m_dyld_image_infos.size())
if (exe_idx < image_infos.size())
{
ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (m_dyld_image_infos[exe_idx], false, NULL));
ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], false, NULL));
if (!exe_module_sp)
{
ArchSpec exe_arch_spec (m_dyld_image_infos[exe_idx].GetArchitecture ());
exe_module_sp = m_process->GetTarget().GetSharedModule (m_dyld_image_infos[exe_idx].file_spec,
ArchSpec exe_arch_spec (image_infos[exe_idx].GetArchitecture ());
exe_module_sp = m_process->GetTarget().GetSharedModule (image_infos[exe_idx].file_spec,
exe_arch_spec,
&m_dyld_image_infos[exe_idx].uuid);
&image_infos[exe_idx].uuid);
}
if (exe_module_sp)

View File

@ -103,19 +103,11 @@ protected:
bool
ReadDYLDInfoFromMemoryAndSetNotificationCallback (lldb::addr_t addr);
uint32_t
UpdateAllImageInfos ();
static bool
NotifyBreakpointHit (void *baton,
lldb_private::StoppointCallbackContext *context,
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
void
UpdateAllImageInfosHeaderAndLoadCommands ();
bool
UpdateCommPageLoadAddress (lldb_private::Module *module);
uint32_t
AddrByteSize()
@ -380,8 +372,42 @@ protected:
bool
SetNotificationBreakpoint ();
// There is a little tricky bit where you might initially attach while dyld is updating
// the all_image_infos, and you can't read the infos, so you have to continue and pick it
// up when you hit the update breakpoint. At that point, you need to run this initialize
// function, but when you do it that way you DON'T need to do the extra work you would at
// the breakpoint.
// So this function will only do actual work if the image infos haven't been read yet.
// If it does do any work, then it will return true, and false otherwise. That way you can
// call it in the breakpoint action, and if it returns true you're done.
bool
InitializeFromAllImageInfos ();
bool
ReadAllImageInfosStructure ();
bool
AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
bool
AddModulesUsingImageInfos (DYLDImageInfo::collection &image_infos);
bool
RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count);
void
UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::collection &image_infos,
uint32_t infos_count,
bool update_executable);
bool
UpdateCommPageLoadAddress (lldb_private::Module *module);
bool
ReadImageInfos (lldb::addr_t image_infos_addr,
uint32_t image_infos_count,
DYLDImageInfo::collection &image_infos);
DYLDImageInfo m_dyld; // Info about the current dyld being used
lldb::addr_t m_dyld_all_image_infos_addr;

View File

@ -27,6 +27,8 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
Thread *thread = process->GetThreadList().GetSelectedThread().get();
if (thread == NULL)
thread = process->GetThreadList().GetThreadAtIndex(0).get();
if (thread == NULL)
return false;
const bool append = true;
const bool include_symbols = true;

View File

@ -1897,6 +1897,9 @@ Process::ReadScalarIntegerFromMemory (addr_t addr,
addr_t
Process::AllocateMemory(size_t size, uint32_t permissions, Error &error)
{
if (GetPrivateState() != eStateStopped)
return LLDB_INVALID_ADDRESS;
#if defined (USE_ALLOCATE_MEMORY_CACHE)
return m_allocated_memory_cache.AllocateMemory(size, permissions, error);
#else

View File

@ -44,8 +44,13 @@ class GenericTester(TestBase):
# Bring the program to the point where we can issue a series of
# 'frame variable -T' command.
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
self.runCmd("breakpoint set --name Puts")
self.runCmd("run", RUN_SUCCEEDED)
puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on before stepping out")
self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line,
BREAKPOINT_CREATED,
startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" %
puts_line)
self.expect("run", RUN_SUCCEEDED, patterns = [".*"])
self.runCmd("thread step-out", STEP_OUT_SUCCEEDED)
#self.runCmd("frame variable -T")
@ -104,8 +109,16 @@ class GenericTester(TestBase):
# Bring the program to the point where we can issue a series of
# 'expr' command.
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
self.runCmd("breakpoint set --name Puts")
self.runCmd("run", RUN_SUCCEEDED)
#self.runCmd("breakpoint set --name Puts")
#self.runCmd("run", RUN_SUCCEEDED)
puts_line = line_number ("basic_type.cpp", "// Here is the line we will break on before stepping out")
self.expect("breakpoint set -f basic_type.cpp -l %d" % puts_line,
BREAKPOINT_CREATED,
startstr = "Breakpoint created: 1: file ='basic_type.cpp', line = %d, locations = 1" %
puts_line)
self.expect("run", RUN_SUCCEEDED, patterns = [".*"])
self.runCmd ("process status")
self.runCmd("thread step-out", STEP_OUT_SUCCEEDED)
#self.runCmd("frame variable -T")

View File

@ -84,7 +84,7 @@ typedef struct a_union_nonzero_tag {
void Puts(char const *msg)
{
puts(msg);
puts(msg); // Here is the line we will break on before stepping out
}
int