forked from OSchip/llvm-project
Added the ability to download a symboled executable and symbol file given a UUID.
llvm-svn: 164753
This commit is contained in:
parent
c36b184fa2
commit
c8f814d1df
|
@ -61,6 +61,10 @@ public:
|
|||
m_packet.clear();
|
||||
}
|
||||
|
||||
// Beware, this might not be NULL terminated as you can expect from
|
||||
// StringString as there may be random bits in the llvm::SmallVector. If
|
||||
// you are using this class to create a C string, be sure the call PutChar ('\0')
|
||||
// after you have created your string, or use StreamString.
|
||||
const char *
|
||||
GetData () const
|
||||
{
|
||||
|
|
|
@ -420,7 +420,8 @@ public:
|
|||
int *status_ptr, // Pass NULL if you don't want the process exit status
|
||||
int *signo_ptr, // Pass NULL if you don't want the signal that caused the process to exit
|
||||
std::string *command_output, // Pass NULL if you don't want the command output
|
||||
uint32_t timeout_sec); // Timeout in seconds to wait for shell program to finish
|
||||
uint32_t timeout_sec,
|
||||
const char *shell = "/bin/bash");
|
||||
|
||||
static lldb::DataBufferSP
|
||||
GetAuxvData (lldb_private::Process *process);
|
||||
|
|
|
@ -24,9 +24,21 @@ namespace lldb_private {
|
|||
class Symbols
|
||||
{
|
||||
public:
|
||||
//----------------------------------------------------------------------
|
||||
// Locate the executable file given a module specification.
|
||||
//
|
||||
// Locating the file should happen only on the local computer or using
|
||||
// the current computers global settings.
|
||||
//----------------------------------------------------------------------
|
||||
static FileSpec
|
||||
LocateExecutableObjectFile (const ModuleSpec &module_spec);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Locate the symbol file given a module specification.
|
||||
//
|
||||
// Locating the file should happen only on the local computer or using
|
||||
// the current computers global settings.
|
||||
//----------------------------------------------------------------------
|
||||
static FileSpec
|
||||
LocateExecutableSymbolFile (const ModuleSpec &module_spec);
|
||||
|
||||
|
@ -34,6 +46,17 @@ public:
|
|||
FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
|
||||
const lldb_private::UUID *uuid,
|
||||
const ArchSpec *arch);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Locate the object and symbol file given a module specification.
|
||||
//
|
||||
// Locating the file can try to download the file from a corporate build
|
||||
// respository, or using any other meeans necessary to locate both the
|
||||
// unstripped object file and the debug symbols.
|
||||
//----------------------------------------------------------------------
|
||||
static bool
|
||||
DownloadObjectAndSymbolFile (ModuleSpec &module_spec);
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Core/Timer.h"
|
||||
#include "lldb/Core/ValueObjectVariable.h"
|
||||
#include "lldb/Host/Symbols.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/CommandReturnObject.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
|
@ -4056,7 +4057,32 @@ protected:
|
|||
symfile_spec.SetFile(symfile_path, true);
|
||||
|
||||
ArchSpec arch;
|
||||
if (symfile_spec.Exists())
|
||||
bool symfile_exists = symfile_spec.Exists();
|
||||
// The code below was testing the new "Symbols::DownloadObjectAndSymbolFile"
|
||||
// functionality. Now that it works on MacOSX, it will be enabled soon with
|
||||
// option values (like "--uuid <UUID>" or "--file <module>", or "--frame"
|
||||
// for the current stack frame's module). So it is commented out for now.
|
||||
// if (!symfile_exists)
|
||||
// {
|
||||
// if (sym_spec.GetUUID().SetfromCString(symfile_path))
|
||||
// {
|
||||
// // A UUID was specified, look it up via UUID
|
||||
// if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
|
||||
// {
|
||||
//// printf ("UUID: %s\n", symfile_path);
|
||||
//// printf ("objfile_spec: %s/%s\n",
|
||||
//// sym_spec.GetFileSpec().GetDirectory().GetCString(),
|
||||
//// sym_spec.GetFileSpec().GetFilename().GetCString());
|
||||
//// printf ("symfile_spec: %s/%s\n",
|
||||
//// sym_spec.GetSymbolFileSpec().GetDirectory().GetCString(),
|
||||
//// sym_spec.GetSymbolFileSpec().GetFilename().GetCString());
|
||||
// symfile_spec = sym_spec.GetSymbolFileSpec();
|
||||
// symfile_exists = symfile_spec.Exists();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (symfile_exists)
|
||||
{
|
||||
ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
|
||||
const UUID &symfile_uuid = symfile_module_sp->GetUUID();
|
||||
|
@ -4111,6 +4137,21 @@ protected:
|
|||
}
|
||||
else
|
||||
{
|
||||
// sym_spec.GetSymbolFileSpec().Clear();
|
||||
// if (sym_spec.GetUUID().SetfromCString(symfile_path))
|
||||
// {
|
||||
// if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
|
||||
// {
|
||||
// printf ("UUID: %s\n", symfile_path);
|
||||
// printf ("objfile_spec: %s/%s\n",
|
||||
// sym_spec.GetFileSpec().GetDirectory().GetCString(),
|
||||
// sym_spec.GetFileSpec().GetFilename().GetCString());
|
||||
// printf ("symfile_spec: %s/%s\n",
|
||||
// sym_spec.GetSymbolFileSpec().GetDirectory().GetCString(),
|
||||
// sym_spec.GetSymbolFileSpec().GetFilename().GetCString());
|
||||
// }
|
||||
// }
|
||||
|
||||
char resolved_symfile_path[PATH_MAX];
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
|
||||
|
|
|
@ -66,9 +66,12 @@ char *
|
|||
UUID::GetAsCString (char *dst, size_t dst_len) const
|
||||
{
|
||||
const uint8_t *u = (const uint8_t *)GetBytes();
|
||||
snprintf(dst, dst_len, "%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
|
||||
u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]);
|
||||
return dst;
|
||||
if (dst_len > snprintf (dst,
|
||||
dst_len,
|
||||
"%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
|
||||
u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]))
|
||||
return dst;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1312,19 +1312,32 @@ Host::RunShellCommand (const char *command,
|
|||
int *status_ptr,
|
||||
int *signo_ptr,
|
||||
std::string *command_output_ptr,
|
||||
uint32_t timeout_sec)
|
||||
uint32_t timeout_sec,
|
||||
const char *shell)
|
||||
{
|
||||
Error error;
|
||||
ProcessLaunchInfo launch_info;
|
||||
launch_info.SetShell("/bin/bash");
|
||||
launch_info.GetArguments().AppendArgument(command);
|
||||
const bool localhost = true;
|
||||
const bool will_debug = false;
|
||||
const bool first_arg_is_full_shell_command = true;
|
||||
launch_info.ConvertArgumentsForLaunchingInShell (error,
|
||||
localhost,
|
||||
will_debug,
|
||||
first_arg_is_full_shell_command);
|
||||
if (shell && shell[0])
|
||||
{
|
||||
// Run the command in a shell
|
||||
launch_info.SetShell(shell);
|
||||
launch_info.GetArguments().AppendArgument(command);
|
||||
const bool localhost = true;
|
||||
const bool will_debug = false;
|
||||
const bool first_arg_is_full_shell_command = true;
|
||||
launch_info.ConvertArgumentsForLaunchingInShell (error,
|
||||
localhost,
|
||||
will_debug,
|
||||
first_arg_is_full_shell_command);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No shell, just run it
|
||||
Args args (command);
|
||||
const bool first_arg_is_executable = true;
|
||||
const bool first_arg_is_executable_and_argument = true;
|
||||
launch_info.SetArguments(args, first_arg_is_executable, first_arg_is_executable_and_argument);
|
||||
}
|
||||
|
||||
if (working_dir)
|
||||
launch_info.SetWorkingDirectory(working_dir);
|
||||
|
@ -1338,7 +1351,7 @@ Host::RunShellCommand (const char *command,
|
|||
output_file_path = ::tmpnam(output_file_path_buffer);
|
||||
launch_info.AppendSuppressFileAction (STDIN_FILENO, true, false);
|
||||
launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_path, false, true);
|
||||
launch_info.AppendDuplicateFileAction(STDERR_FILENO, STDOUT_FILENO);
|
||||
launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -36,5 +36,13 @@ Symbols::FindSymbolFileInBundle (const FileSpec& symfile_bundle,
|
|||
return FileSpec();
|
||||
}
|
||||
|
||||
bool
|
||||
Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec)
|
||||
{
|
||||
// Fill in the module_spec.GetFileSpec() for the object file and/or the
|
||||
// module_spec.GetSymbolFileSpec() for the debug symbols file.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1552,7 +1552,6 @@ LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, :
|
|||
argv = (char * const*)tmp_argv;
|
||||
}
|
||||
|
||||
|
||||
const char *working_dir = launch_info.GetWorkingDirectory();
|
||||
if (working_dir)
|
||||
{
|
||||
|
@ -1605,13 +1604,21 @@ LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, :
|
|||
eErrorTypePOSIX);
|
||||
|
||||
if (error.Fail() || log)
|
||||
error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
|
||||
{
|
||||
error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
|
||||
pid,
|
||||
exe_path,
|
||||
&file_actions,
|
||||
&attr,
|
||||
argv,
|
||||
envp);
|
||||
if (log)
|
||||
{
|
||||
for (int ii=0; argv[ii]; ++ii)
|
||||
log->Printf("argv[%i] = '%s'", ii, argv[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1624,12 +1631,19 @@ LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, :
|
|||
eErrorTypePOSIX);
|
||||
|
||||
if (error.Fail() || log)
|
||||
error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
|
||||
{
|
||||
error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
|
||||
pid,
|
||||
exe_path,
|
||||
&attr,
|
||||
argv,
|
||||
envp);
|
||||
if (log)
|
||||
{
|
||||
for (int ii=0; argv[ii]; ++ii)
|
||||
log->Printf("argv[%i] = '%s'", ii, argv[ii]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (working_dir)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Utility/CleanUp.h"
|
||||
#include "Host/macosx/cfcpp/CFCBundle.h"
|
||||
#include "Host/macosx/cfcpp/CFCData.h"
|
||||
#include "Host/macosx/cfcpp/CFCReleaser.h"
|
||||
#include "Host/macosx/cfcpp/CFCString.h"
|
||||
#include "mach/machine.h"
|
||||
|
@ -582,3 +583,102 @@ Symbols::LocateExecutableSymbolFile (const ModuleSpec &module_spec)
|
|||
}
|
||||
return symbol_fspec;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool
|
||||
Symbols::DownloadObjectAndSymbolFile (ModuleSpec &module_spec)
|
||||
{
|
||||
bool success = false;
|
||||
const UUID *uuid_ptr = module_spec.GetUUIDPtr();
|
||||
if (uuid_ptr)
|
||||
{
|
||||
static bool g_located_dsym_for_uuid_exe = false;
|
||||
static bool g_dsym_for_uuid_exe_exists = false;
|
||||
static char g_dsym_for_uuid_exe_path[PATH_MAX];
|
||||
if (!g_located_dsym_for_uuid_exe)
|
||||
{
|
||||
g_located_dsym_for_uuid_exe = true;
|
||||
const char *dsym_for_uuid_exe_path_cstr = getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
|
||||
FileSpec dsym_for_uuid_exe_spec;
|
||||
if (dsym_for_uuid_exe_path_cstr)
|
||||
{
|
||||
dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true);
|
||||
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
|
||||
}
|
||||
|
||||
if (!g_dsym_for_uuid_exe_exists)
|
||||
{
|
||||
dsym_for_uuid_exe_spec.SetFile("~rc/bin/dsymForUUID", true);
|
||||
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
|
||||
if (!g_dsym_for_uuid_exe_exists)
|
||||
{
|
||||
dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_dsym_for_uuid_exe_exists)
|
||||
dsym_for_uuid_exe_spec.GetPath (g_dsym_for_uuid_exe_path, sizeof(g_dsym_for_uuid_exe_path));
|
||||
}
|
||||
if (g_dsym_for_uuid_exe_exists)
|
||||
{
|
||||
StreamString command;
|
||||
char uuid_cstr_buffer[64];
|
||||
const char *uuid_cstr = uuid_ptr->GetAsCString(uuid_cstr_buffer, sizeof(uuid_cstr_buffer));
|
||||
command.Printf("%s --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_cstr);
|
||||
int exit_status = -1;
|
||||
int signo = -1;
|
||||
std::string command_output;
|
||||
Error error = Host::RunShellCommand (command.GetData(),
|
||||
NULL, // current working directory
|
||||
&exit_status, // Exit status
|
||||
&signo, // Signal int *
|
||||
&command_output, // Command output
|
||||
30, // Large timeout to allow for long dsym download times
|
||||
NULL); // Don't run in a shell (we don't need shell expansion)
|
||||
if (error.Success() && exit_status == 0 && !command_output.empty())
|
||||
{
|
||||
CFCData data (CFDataCreateWithBytesNoCopy (NULL,
|
||||
(const UInt8 *)command_output.data(),
|
||||
command_output.size(),
|
||||
kCFAllocatorNull));
|
||||
|
||||
CFCReleaser<CFPropertyListRef> plist(::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL));
|
||||
|
||||
if (CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
|
||||
{
|
||||
std::string str;
|
||||
CFCString uuid_cfstr(uuid_cstr);
|
||||
CFTypeRef uuid_dict = CFDictionaryGetValue ((CFDictionaryRef) plist.get(), uuid_cfstr.get());
|
||||
if (uuid_dict != NULL && CFGetTypeID (uuid_dict) == CFDictionaryGetTypeID ())
|
||||
{
|
||||
CFStringRef cf_str;
|
||||
|
||||
cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGSymbolRichExecutable"));
|
||||
if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
|
||||
{
|
||||
if (CFCString::FileSystemRepresentation(cf_str, str))
|
||||
{
|
||||
success = true;
|
||||
module_spec.GetFileSpec().SetFile (str.c_str(), true);
|
||||
}
|
||||
}
|
||||
|
||||
cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGDSYMPath"));
|
||||
if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
|
||||
{
|
||||
if (CFCString::FileSystemRepresentation(cf_str, str))
|
||||
{
|
||||
success = true;
|
||||
module_spec.GetSymbolFileSpec().SetFile (str.c_str(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue