summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2012-09-27 03:13:55 +0000
committerGreg Clayton <gclayton@apple.com>2012-09-27 03:13:55 +0000
commitc8f814d1dfec8f162c86b71973f16cea0f229aa7 (patch)
tree97e10e1c005700bb61ebf6e613c30e8d16474459
parentc36b184fa2a8cbd083df03664da1f2c1fc264c31 (diff)
downloadbcm5719-llvm-c8f814d1dfec8f162c86b71973f16cea0f229aa7.tar.gz
bcm5719-llvm-c8f814d1dfec8f162c86b71973f16cea0f229aa7.zip
Added the ability to download a symboled executable and symbol file given a UUID.
llvm-svn: 164753
-rw-r--r--lldb/include/lldb/Core/StreamBuffer.h4
-rw-r--r--lldb/include/lldb/Host/Host.h3
-rw-r--r--lldb/include/lldb/Host/Symbols.h23
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp43
-rw-r--r--lldb/source/Core/UUID.cpp9
-rw-r--r--lldb/source/Host/common/Host.cpp35
-rw-r--r--lldb/source/Host/common/Symbols.cpp8
-rw-r--r--lldb/source/Host/macosx/Host.mm20
-rw-r--r--lldb/source/Host/macosx/Symbols.cpp100
9 files changed, 226 insertions, 19 deletions
diff --git a/lldb/include/lldb/Core/StreamBuffer.h b/lldb/include/lldb/Core/StreamBuffer.h
index e9cd756be2a..358f39b37b7 100644
--- a/lldb/include/lldb/Core/StreamBuffer.h
+++ b/lldb/include/lldb/Core/StreamBuffer.h
@@ -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
{
diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h
index e41f15ac3b4..1e2b327fe1c 100644
--- a/lldb/include/lldb/Host/Host.h
+++ b/lldb/include/lldb/Host/Host.h
@@ -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);
diff --git a/lldb/include/lldb/Host/Symbols.h b/lldb/include/lldb/Host/Symbols.h
index 7e997cc76cd..4dd8fed6beb 100644
--- a/lldb/include/lldb/Host/Symbols.h
+++ b/lldb/include/lldb/Host/Symbols.h
@@ -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
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index ee224b6f563..c1e6486f035 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -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)))
diff --git a/lldb/source/Core/UUID.cpp b/lldb/source/Core/UUID.cpp
index 37d1eaa738d..520e31e8070 100644
--- a/lldb/source/Core/UUID.cpp
+++ b/lldb/source/Core/UUID.cpp
@@ -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
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index 400f493d2c3..4ed06c000d0 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -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
{
diff --git a/lldb/source/Host/common/Symbols.cpp b/lldb/source/Host/common/Symbols.cpp
index 464c2fc5784..177d7042cd5 100644
--- a/lldb/source/Host/common/Symbols.cpp
+++ b/lldb/source/Host/common/Symbols.cpp
@@ -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
diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm
index 8748184693e..cc7045247c6 100644
--- a/lldb/source/Host/macosx/Host.mm
+++ b/lldb/source/Host/macosx/Host.mm
@@ -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)
diff --git a/lldb/source/Host/macosx/Symbols.cpp b/lldb/source/Host/macosx/Symbols.cpp
index c49592eddc7..f7f08c80738 100644
--- a/lldb/source/Host/macosx/Symbols.cpp
+++ b/lldb/source/Host/macosx/Symbols.cpp
@@ -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;
+}
+
OpenPOWER on IntegriCloud