Added the ability to download a symboled executable and symbol file given a UUID.
llvm-svn: 164753
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index ee224b6..c1e6486 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 @@
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 @@
}
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 37d1eaa..520e31e 100644
--- a/lldb/source/Core/UUID.cpp
+++ b/lldb/source/Core/UUID.cpp
@@ -66,9 +66,12 @@
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 400f493..4ed06c0 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -1312,19 +1312,32 @@
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 @@
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 464c2fc..177d704 100644
--- a/lldb/source/Host/common/Symbols.cpp
+++ b/lldb/source/Host/common/Symbols.cpp
@@ -36,5 +36,13 @@
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 8748184..cc70452 100644
--- a/lldb/source/Host/macosx/Host.mm
+++ b/lldb/source/Host/macosx/Host.mm
@@ -1552,7 +1552,6 @@
argv = (char * const*)tmp_argv;
}
-
const char *working_dir = launch_info.GetWorkingDirectory();
if (working_dir)
{
@@ -1605,13 +1604,21 @@
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 @@
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 c49592ed..f7f08c8 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 @@
}
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;
+}
+