diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index cb37c09786f6..92076d75bc5d 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -4047,6 +4047,10 @@ protected: if (symfile_spec.Exists()) { ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture())); + const UUID &symfile_uuid = symfile_module_sp->GetUUID(); + StreamString ss_symfile_uuid; + symfile_module_sp->GetUUID().Dump(&ss_symfile_uuid); + if (symfile_module_sp) { // We now have a module that represents a symbol file @@ -4054,7 +4058,7 @@ protected: // current target, so we need to find that module in the // target - ModuleSP old_module_sp (target->GetImages().FindModule (symfile_module_sp->GetUUID())); + ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid)); if (old_module_sp) { // The module has not yet created its symbol vendor, we can just @@ -4062,6 +4066,12 @@ protected: // when it decides to create it! old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec()); + // Provide feedback that the symfile has been successfully added. + const FileSpec &module_fs = old_module_sp->GetFileSpec(); + result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n", + symfile_path, ss_symfile_uuid.GetData(), + module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString()); + // Let clients know something changed in the module // if it is currently loaded ModuleList module_list; @@ -4069,6 +4079,15 @@ protected: target->ModulesDidLoad (module_list); flush = true; } + else + { + result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n", + symfile_path, ss_symfile_uuid.GetData(), + (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular) + ? "\n please specify the full path to the symbol file" + : ""); + break; + } } else { diff --git a/lldb/source/Host/macosx/Symbols.cpp b/lldb/source/Host/macosx/Symbols.cpp index debd85d20ab6..9274decda0e7 100644 --- a/lldb/source/Host/macosx/Symbols.cpp +++ b/lldb/source/Host/macosx/Symbols.cpp @@ -22,6 +22,7 @@ #include "lldb/Core/DataBuffer.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Module.h" +#include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" #include "lldb/Core/UUID.h" #include "lldb/Host/Endian.h" @@ -126,9 +127,12 @@ SkinnyMachOFileContainsArchAndUUID path_buf[0] = '\0'; const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf : file_spec.GetFilename().AsCString(); + StreamString ss_m_uuid, ss_o_uuid; + uuid->Dump(&ss_m_uuid); + file_uuid.Dump(&ss_o_uuid); Host::SystemLog (Host::eSystemLogWarning, - "warning: UUID mismatch detected between binary and:\n\t'%s'\n", - path); + "warning: UUID mismatch detected between binary (%s) and:\n\t'%s' (%s)\n", + ss_m_uuid.GetData(), path, ss_o_uuid.GetData()); return false; } data_offset = cmd_offset + cmd_size; diff --git a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp index a3f6445201fc..36dc39da13e6 100644 --- a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp +++ b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp @@ -18,7 +18,9 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" +#include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" +#include "lldb/Host/Host.h" #include "lldb/Host/Symbols.h" #include "lldb/Symbol/ObjectFile.h" @@ -50,6 +52,20 @@ UUIDsMatch(Module *module, ObjectFile *ofile) lldb_private::UUID dsym_uuid; if (ofile->GetUUID(&dsym_uuid)) return dsym_uuid == module->GetUUID(); + + // Emit some warning messages since the UUIDs do not match! + const FileSpec &m_file_spec = module->GetFileSpec(); + const FileSpec &o_file_spec = ofile->GetFileSpec(); + StreamString ss_m_path, ss_o_path; + m_file_spec.Dump(&ss_m_path); + o_file_spec.Dump(&ss_o_path); + + StreamString ss_m_uuid, ss_o_uuid; + module->GetUUID().Dump(&ss_m_uuid); + dsym_uuid.Dump(&ss_o_uuid); + Host::SystemLog (Host::eSystemLogWarning, + "warning: UUID mismatch detected between module '%s' (%s) and:\n\t'%s' (%s)\n", + ss_m_path.GetData(), ss_m_uuid.GetData(), ss_o_path.GetData(), ss_o_uuid.GetData()); } return false; } diff --git a/lldb/test/warnings/uuid/TestAddDsymCommand.py b/lldb/test/warnings/uuid/TestAddDsymCommand.py new file mode 100644 index 000000000000..d7b348734999 --- /dev/null +++ b/lldb/test/warnings/uuid/TestAddDsymCommand.py @@ -0,0 +1,91 @@ +"""Test that the 'add-dsym', aka 'target symbols add', command informs the user about success or failure.""" + +import os, time +import unittest2 +import lldb +import pexpect +from lldbtest import * + +@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") +class AddDsymCommandCase(TestBase): + + mydir = os.path.join("warnings", "uuid") + + def setUp(self): + TestBase.setUp(self) + self.template = 'main.cpp.template' + self.source = 'main.cpp' + self.teardown_hook_added = False + + def test_add_dsym_command_with_error(self): + """Test that the 'add-dsym' command informs the user about failures.""" + + # Call the program generator to produce main.cpp, version 1. + self.generate_main_cpp(version=1) + self.buildDsym(clean=True) + + # Insert some delay and then call the program generator to produce main.cpp, version 2. + time.sleep(5) + self.generate_main_cpp(version=101) + # Now call make again, but this time don't generate the dSYM. + self.buildDwarf(clean=False) + + self.exe_name = 'a.out' + self.do_add_dsym_with_error(self.exe_name) + + def test_add_dsym_command_with_success(self): + """Test that the 'add-dsym' command informs the user about success.""" + + # Call the program generator to produce main.cpp, version 1. + self.generate_main_cpp(version=1) + self.buildDsym(clean=True) + + self.exe_name = 'a.out' + self.do_add_dsym_with_success(self.exe_name) + + def generate_main_cpp(self, version=0): + """Generate main.cpp from main.cpp.template.""" + temp = os.path.join(os.getcwd(), self.template) + with open(temp, 'r') as f: + content = f.read() + + new_content = content.replace('%ADD_EXTRA_CODE%', + 'printf("This is version %d\\n");' % version) + src = os.path.join(os.getcwd(), self.source) + with open(src, 'w') as f: + f.write(new_content) + + # The main.cpp has been generated, add a teardown hook to remove it. + if not self.teardown_hook_added: + self.addTearDownHook(lambda: os.remove(src)) + self.teardown_hook_added = True + + def do_add_dsym_with_error(self, exe_name): + """Test that the 'add-dsym' command informs the user about failures.""" + self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET) + + wrong_path = "%s.dSYM" % exe_name + self.expect("add-dsym " + wrong_path, error=True, + substrs = ['symbol file', 'with UUID', 'does not match', + 'please specify the full path to the symbol file']) + + right_path = os.path.join(wrong_path, "Contents", "Resources", "DWARF", exe_name) + self.expect("add-dsym " + right_path, error=True, + substrs = ['symbol file', 'with UUID', 'does not match']) + + def do_add_dsym_with_success(self, exe_name): + """Test that the 'add-dsym' command informs the user about success.""" + self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET) + + # This time, the UUID should match and we expect some feedback from lldb. + right_path = os.path.join("%s.dSYM" % exe_name, "Contents", "Resources", "DWARF", exe_name) + self.expect("add-dsym " + right_path, + substrs = ['symbol file', 'with UUID', 'has been successfully added to the', + 'module']) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main()