From 23629167fefb8117a4d2cc9213c8a29d5b4a1197 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 24 Dec 2017 01:01:00 +0000 Subject: [PATCH] Vendor import of lldb trunk r321414: https://llvm.org/svn/llvm-project/lldb/trunk@321414 --- .../lldb/Interpreter/OptionValueFileSpec.h | 2 +- include/lldb/Symbol/ObjectFile.h | 3 + include/lldb/Target/Target.h | 2 +- include/lldb/Utility/DataBufferLLVM.h | 11 ++- .../radar_9673664/TestExprHelpExamples.py | 2 +- .../expression_command/top-level/test.cpp | 22 +++--- .../test/functionalities/exec/TestExec.py | 2 + .../minidump-new/TestMiniDumpNew.py | 2 +- .../TestConflictingSymbol.py | 45 ++++++++++-- .../lldbsuite/test/lang/cpp/lambdas/main.cpp | 2 +- .../process/read-mem-cstring/Makefile | 6 ++ .../read-mem-cstring/TestReadMemCString.py | 57 +++++++++++++++ .../process/read-mem-cstring/main.c | 11 +++ scripts/Python/python-typemaps.swig | 3 +- source/Interpreter/OptionValueFileSpec.cpp | 6 +- .../Disassembler/llvm/DisassemblerLLVMC.cpp | 5 ++ .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 22 ++---- .../ObjectFile/Mach-O/ObjectFileMachO.cpp | 36 ++++------ .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp | 10 +-- .../Platform/MacOSX/PlatformDarwin.cpp | 2 +- .../MacOSX-Kernel/CommunicationKDP.cpp | 2 +- .../gdb-remote/GDBRemoteClientBase.cpp | 1 + .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 8 +-- .../Plugins/SymbolFile/PDB/PDBASTParser.cpp | 4 ++ .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 72 ++++++++++++++----- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h | 3 +- source/Symbol/ObjectFile.cpp | 5 ++ source/Target/Target.cpp | 13 ++-- source/Utility/DataBufferLLVM.cpp | 28 ++++---- .../debugserver.xcodeproj/project.pbxproj | 34 ++++----- tools/debugserver/source/RNBContext.cpp | 19 +++++ tools/debugserver/source/RNBContext.h | 1 + tools/debugserver/source/debugserver.cpp | 22 +++--- .../lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp | 2 + tools/lldb-mi/MIUtilString.cpp | 5 +- .../SymbolFile/PDB/SymbolFilePDBTests.cpp | 10 ++- unittests/tools/lldb-server/CMakeLists.txt | 4 +- .../tools/lldb-server/tests/LLGSTest.cpp | 22 ++++-- .../tools/lldb-server/tests/TestClient.cpp | 12 ++-- .../tools/lldb-server/tests/TestClient.h | 19 ++++- 40 files changed, 367 insertions(+), 170 deletions(-) create mode 100644 packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/Makefile create mode 100644 packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/TestReadMemCString.py create mode 100644 packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/main.c diff --git a/include/lldb/Interpreter/OptionValueFileSpec.h b/include/lldb/Interpreter/OptionValueFileSpec.h index b53c03471e2b..293ecd0d8054 100644 --- a/include/lldb/Interpreter/OptionValueFileSpec.h +++ b/include/lldb/Interpreter/OptionValueFileSpec.h @@ -77,7 +77,7 @@ class OptionValueFileSpec : public OptionValue { void SetDefaultValue(const FileSpec &value) { m_default_value = value; } - const lldb::DataBufferSP &GetFileContents(bool null_terminate); + const lldb::DataBufferSP &GetFileContents(); void SetCompletionMask(uint32_t mask) { m_completion_mask = mask; } diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h index 3f9250af7e08..dff802522da8 100644 --- a/include/lldb/Symbol/ObjectFile.h +++ b/include/lldb/Symbol/ObjectFile.h @@ -879,6 +879,9 @@ class ObjectFile : public std::enable_shared_from_this, ConstString GetNextSyntheticSymbolName(); + static lldb::DataBufferSP MapFileData(const FileSpec &file, uint64_t Size, + uint64_t Offset); + private: DISALLOW_COPY_AND_ASSIGN(ObjectFile); }; diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index 242ec14165eb..a5d200069810 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -161,7 +161,7 @@ class TargetProperties : public Properties { lldb::LanguageType GetLanguage() const; - const char *GetExpressionPrefixContentsAsCString(); + llvm::StringRef GetExpressionPrefixContents(); bool GetUseHexImmediates() const; diff --git a/include/lldb/Utility/DataBufferLLVM.h b/include/lldb/Utility/DataBufferLLVM.h index 737e2d019044..0eb229cffbe2 100644 --- a/include/lldb/Utility/DataBufferLLVM.h +++ b/include/lldb/Utility/DataBufferLLVM.h @@ -17,7 +17,7 @@ #include // for uint8_t, uint64_t namespace llvm { -class MemoryBuffer; +class WritableMemoryBuffer; class Twine; } @@ -28,10 +28,10 @@ class DataBufferLLVM : public DataBuffer { ~DataBufferLLVM(); static std::shared_ptr - CreateSliceFromPath(const llvm::Twine &Path, uint64_t Size, uint64_t Offset, bool Private = false); + CreateSliceFromPath(const llvm::Twine &Path, uint64_t Size, uint64_t Offset); static std::shared_ptr - CreateFromPath(const llvm::Twine &Path, bool NullTerminate = false, bool Private = false); + CreateFromPath(const llvm::Twine &Path); uint8_t *GetBytes() override; const uint8_t *GetBytes() const override; @@ -42,10 +42,9 @@ class DataBufferLLVM : public DataBuffer { private: /// \brief Construct a DataBufferLLVM from \p Buffer. \p Buffer must be a /// valid pointer. - explicit DataBufferLLVM(std::unique_ptr Buffer); - const uint8_t *GetBuffer() const; + explicit DataBufferLLVM(std::unique_ptr Buffer); - std::unique_ptr Buffer; + std::unique_ptr Buffer; }; } diff --git a/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py b/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py index a6c0c050c468..4fc2463b25a8 100644 --- a/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py +++ b/packages/Python/lldbsuite/test/expression_command/radar_9673664/TestExprHelpExamples.py @@ -42,7 +42,7 @@ def test_expr_commands(self): # rdar://problem/9673664 lldb expression evaluation problem - self.expect('expr char c[] = "foo"; c[0]', + self.expect('expr char str[] = "foo"; str[0]', substrs=["'f'"]) # runCmd: expr char c[] = "foo"; c[0] # output: (char) $0 = 'f' diff --git a/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp b/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp index ce2ea3bbb131..5a978743596a 100644 --- a/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp +++ b/packages/Python/lldbsuite/test/expression_command/top-level/test.cpp @@ -42,11 +42,11 @@ class AnotherClass int i; } s = { 15 }; - int as[4] = { 2, 3, 4, 5 }; + int numbers[4] = { 2, 3, 4, 5 }; - for (signed char a : as) + for (signed char number: numbers) { - s.i -= a; + s.i -= number; } return s.i; @@ -94,14 +94,14 @@ class DiamondD : public DiamondB, public DiamondC int doTest() { - int a = m.memberResult(); - a += MyClass::staticResult(); - a += m.externResult(); - a += MyEnum::myEnumThree; - a += myEnumOne; - a += AnotherClass().complicatedFunction(); - a += DiamondD(3).accessor(); - return a; + int accumulator = m.memberResult(); + accumulator += MyClass::staticResult(); + accumulator += m.externResult(); + accumulator += MyEnum::myEnumThree; + accumulator += myEnumOne; + accumulator += AnotherClass().complicatedFunction(); + accumulator += DiamondD(3).accessor(); + return accumulator; } // -- diff --git a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py index 965af3e4910a..550eae85e1d6 100644 --- a/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py +++ b/packages/Python/lldbsuite/test/functionalities/exec/TestExec.py @@ -29,12 +29,14 @@ class ExecTestCase(TestBase): mydir = TestBase.compute_mydir(__file__) @skipUnlessDarwin + @expectedFailureAll(oslist=['macosx'], bugnumber="rdar://36134350") # when building with cmake on green gragon or on ci.swift.org, this test fails. @expectedFailureAll(archs=['i386'], bugnumber="rdar://28656532") @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems def test_hitting_exec (self): self.do_test(False) @skipUnlessDarwin + @expectedFailureAll(oslist=['macosx'], bugnumber="rdar://36134350") # when building with cmake on green gragon or on ci.swift.org, this test fails. @expectedFailureAll(archs=['i386'], bugnumber="rdar://28656532") @expectedFailureAll(oslist=["ios", "tvos", "watchos", "bridgeos"], bugnumber="rdar://problem/34559552") # this exec test has problems on ios systems def test_skipping_exec (self): diff --git a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py index 178bb678df7c..4e587b92c1d2 100644 --- a/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py +++ b/packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py @@ -117,7 +117,7 @@ def test_snapshot_minidump(self): thread = self.process.GetThreadAtIndex(0) self.assertEqual(thread.GetStopReason(), lldb.eStopReasonNone) stop_description = thread.GetStopDescription(256) - self.assertEqual(stop_description, None) + self.assertEqual(stop_description, "") def do_test_deeper_stack(self, binary, core, pid): target = self.dbg.CreateTarget(binary) diff --git a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py index d3327700bfd2..328c383b38fb 100644 --- a/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py +++ b/packages/Python/lldbsuite/test/lang/c/conflicting-symbol/TestConflictingSymbol.py @@ -16,6 +16,13 @@ class TestConflictingSymbols(TestBase): mydir = TestBase.compute_mydir(__file__) NO_DEBUG_INFO_TESTCASE = True + def setUp(self): + TestBase.setUp(self) + + self.One_line = line_number('One/One.c', '// break here') + self.Two_line = line_number('Two/Two.c', '// break here') + self.main_line = line_number('main.c', '// break here') + def test_conflicting_symbols(self): self.build() exe = os.path.join(os.getcwd(), "a.out") @@ -27,15 +34,12 @@ def test_conflicting_symbols(self): environment = self.registerSharedLibrariesWithTarget( target, ['One', 'Two']) - One_line = line_number('One/One.c', '// break here') - Two_line = line_number('Two/Two.c', '// break here') - main_line = line_number('main.c', '// break here') lldbutil.run_break_set_command( - self, 'breakpoint set -f One.c -l %s' % (One_line)) + self, 'breakpoint set -f One.c -l %s' % (self.One_line)) lldbutil.run_break_set_command( - self, 'breakpoint set -f Two.c -l %s' % (Two_line)) + self, 'breakpoint set -f Two.c -l %s' % (self.Two_line)) lldbutil.run_break_set_by_file_and_line( - self, 'main.c', main_line, num_expected_locations=1, loc_exact=True) + self, 'main.c', self.main_line, num_expected_locations=1, loc_exact=True) process = target.LaunchSimple( None, environment, self.get_process_working_directory()) @@ -88,3 +92,32 @@ def test_conflicting_symbols(self): error=True, substrs=[ "Multiple internal symbols"]) + + @expectedFailureAll(bugnumber="llvm.org/pr35043") + def test_shadowed(self): + self.build() + exe = os.path.join(os.getcwd(), "a.out") + target = self.dbg.CreateTarget("a.out") + self.assertTrue(target, VALID_TARGET) + + # Register our shared libraries for remote targets so they get + # automatically uploaded + environment = self.registerSharedLibrariesWithTarget( + target, ['One', 'Two']) + + lldbutil.run_break_set_by_file_and_line(self, 'main.c', self.main_line) + + process = target.LaunchSimple( + None, environment, self.get_process_working_directory()) + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', + 'stop reason = breakpoint']) + + # As we are shadowing the conflicting symbol, there should be no + # ambiguity in this expression. + self.expect( + "expr int conflicting_symbol = 474747; conflicting_symbol", + substrs=[ "474747"]) diff --git a/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp index 3cce3baf2924..0432cc1357da 100644 --- a/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp +++ b/packages/Python/lldbsuite/test/lang/cpp/lambdas/main.cpp @@ -11,7 +11,7 @@ int main (int argc, char const *argv[]) { - printf("Stop here\n"); //% self.runCmd("expression auto $add = [](int a, int b) { return a + b; }") + printf("Stop here\n"); //% self.runCmd("expression auto $add = [](int first, int second) { return first + second; }") //% self.expect("expression $add(2,3)", substrs = ['= 5']) return 0; } diff --git a/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/Makefile b/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/Makefile new file mode 100644 index 000000000000..f3414925f32b --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/Makefile @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +EXE := read-mem-cstring + +include $(LEVEL)/Makefile.rules diff --git a/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/TestReadMemCString.py b/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/TestReadMemCString.py new file mode 100644 index 000000000000..6302711606c5 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/TestReadMemCString.py @@ -0,0 +1,57 @@ +"""Test reading c-strings from memory via SB API.""" + +from __future__ import print_function + +import os +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestReadMemCString(TestBase): + + mydir = TestBase.compute_mydir(__file__) + NO_DEBUG_INFO_TESTCASE = True + + def test_read_memory_c_string(self): + """Test corner case behavior of SBProcess::ReadCStringFromMemory""" + self.build() + self.dbg.SetAsync(False) + + self.main_source = "main.c" + self.main_source_spec = lldb.SBFileSpec(self.main_source) + self.exe = os.path.join(os.getcwd(), "read-mem-cstring") + + (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint( + self, 'breakpoint here', self.main_source_spec, None, self.exe) + + frame = thread.GetFrameAtIndex(0) + + err = lldb.SBError() + + empty_str_addr = frame.FindVariable("empty_string").GetValueAsUnsigned(err) + self.assertTrue(err.Success()) + self.assertTrue(empty_str_addr != lldb.LLDB_INVALID_ADDRESS) + + one_letter_str_addr = frame.FindVariable("one_letter_string").GetValueAsUnsigned(err) + self.assertTrue(err.Success()) + self.assertTrue(one_letter_str_addr != lldb.LLDB_INVALID_ADDRESS) + + invalid_memory_str_addr = frame.FindVariable("invalid_memory_string").GetValueAsUnsigned(err) + self.assertTrue(err.Success()) + self.assertTrue(invalid_memory_str_addr != lldb.LLDB_INVALID_ADDRESS) + + # Important: An empty (0-length) c-string must come back as a Python string, not a + # None object. + empty_str = process.ReadCStringFromMemory(empty_str_addr, 2048, err) + self.assertTrue(err.Success()) + self.assertTrue(empty_str == "") + + one_letter_string = process.ReadCStringFromMemory(one_letter_str_addr, 2048, err) + self.assertTrue(err.Success()) + self.assertTrue(one_letter_string == "1") + + invalid_memory_string = process.ReadCStringFromMemory(invalid_memory_str_addr, 2048, err) + self.assertTrue(err.Fail()) + self.assertTrue(invalid_memory_string == "" or invalid_memory_string == None) diff --git a/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/main.c b/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/main.c new file mode 100644 index 000000000000..03c667417129 --- /dev/null +++ b/packages/Python/lldbsuite/test/python_api/process/read-mem-cstring/main.c @@ -0,0 +1,11 @@ +#include +int main () +{ + const char *empty_string = ""; + const char *one_letter_string = "1"; + // This expects that lower 4k of memory will be mapped unreadable, which most + // OSs do (to catch null pointer dereferences). + const char *invalid_memory_string = (char*)0x100; + + return empty_string[0] + one_letter_string[0]; // breakpoint here +} diff --git a/scripts/Python/python-typemaps.swig b/scripts/Python/python-typemaps.swig index df16a6d27b3b..29e5d9b156df 100644 --- a/scripts/Python/python-typemaps.swig +++ b/scripts/Python/python-typemaps.swig @@ -102,7 +102,8 @@ %typemap(argout) (char *dst, size_t dst_len) { Py_XDECREF($result); /* Blow away any previous result */ if (result == 0) { - $result = Py_None; + lldb_private::PythonString string(""); + $result = string.release(); Py_INCREF($result); } else { llvm::StringRef ref(static_cast($1), result); diff --git a/source/Interpreter/OptionValueFileSpec.cpp b/source/Interpreter/OptionValueFileSpec.cpp index b235d4ac6863..7d17ddec4f9c 100644 --- a/source/Interpreter/OptionValueFileSpec.cpp +++ b/source/Interpreter/OptionValueFileSpec.cpp @@ -113,14 +113,12 @@ size_t OptionValueFileSpec::AutoComplete( return matches.GetSize(); } -const lldb::DataBufferSP & -OptionValueFileSpec::GetFileContents(bool null_terminate) { +const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() { if (m_current_value) { const auto file_mod_time = FileSystem::GetModificationTime(m_current_value); if (m_data_sp && m_data_mod_time == file_mod_time) return m_data_sp; - m_data_sp = DataBufferLLVM::CreateFromPath(m_current_value.GetPath(), - null_terminate); + m_data_sp = DataBufferLLVM::CreateFromPath(m_current_value.GetPath()); m_data_mod_time = file_mod_time; } return m_data_sp; diff --git a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index 21e19bf2b127..a61abb9898ac 100644 --- a/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -1127,6 +1127,11 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, features_str += "+dspr2,"; } + // If any AArch64 variant, enable the ARMv8.2 ISA + // extensions so we can disassemble newer instructions. + if (triple.getArch() == llvm::Triple::aarch64) + features_str += "+v8.2a"; + m_disasm_ap.reset(new LLVMCDisassembler(triple_str, cpu, features_str.c_str(), flavor, *this)); if (!m_disasm_ap->IsValid()) { diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 17d892450e4d..36027dde0432 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -24,7 +24,6 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" @@ -406,8 +405,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, lldb::offset_t file_offset, lldb::offset_t length) { if (!data_sp) { - data_sp = - DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset, true); + data_sp = MapFileData(*file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; @@ -424,8 +422,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, // Update the data to contain the entire file if it doesn't already if (data_sp->GetByteSize() < length) { - data_sp = - DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset, true); + data_sp = MapFileData(*file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; @@ -684,8 +681,7 @@ size_t ObjectFileELF::GetModuleSpecifications( size_t section_header_end = header.e_shoff + header.e_shentsize; if (header.HasHeaderExtension() && section_header_end > data_sp->GetByteSize()) { - data_sp = DataBufferLLVM::CreateSliceFromPath( - file.GetPath(), section_header_end, file_offset); + data_sp = MapFileData(file, section_header_end, file_offset); if (data_sp) { data.SetData(data_sp); lldb::offset_t header_offset = data_offset; @@ -698,8 +694,7 @@ size_t ObjectFileELF::GetModuleSpecifications( section_header_end = header.e_shoff + header.e_shnum * header.e_shentsize; if (section_header_end > data_sp->GetByteSize()) { - data_sp = DataBufferLLVM::CreateSliceFromPath( - file.GetPath(), section_header_end, file_offset); + data_sp = MapFileData(file, section_header_end, file_offset); if (data_sp) data.SetData(data_sp); } @@ -741,8 +736,7 @@ size_t ObjectFileELF::GetModuleSpecifications( size_t program_headers_end = header.e_phoff + header.e_phnum * header.e_phentsize; if (program_headers_end > data_sp->GetByteSize()) { - data_sp = DataBufferLLVM::CreateSliceFromPath( - file.GetPath(), program_headers_end, file_offset); + data_sp = MapFileData(file, program_headers_end, file_offset); if (data_sp) data.SetData(data_sp); } @@ -757,8 +751,7 @@ size_t ObjectFileELF::GetModuleSpecifications( } if (segment_data_end > data_sp->GetByteSize()) { - data_sp = DataBufferLLVM::CreateSliceFromPath( - file.GetPath(), segment_data_end, file_offset); + data_sp = MapFileData(file, segment_data_end, file_offset); if (data_sp) data.SetData(data_sp); } @@ -767,8 +760,7 @@ size_t ObjectFileELF::GetModuleSpecifications( CalculateELFNotesSegmentsCRC32(program_headers, data); } else { // Need to map entire file into memory to calculate the crc. - data_sp = DataBufferLLVM::CreateSliceFromPath(file.GetPath(), -1, - file_offset); + data_sp = MapFileData(file, -1, file_offset); if (data_sp) { data.SetData(data_sp); gnu_debuglink_crc = calc_gnu_debuglink_crc32( diff --git a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index df334f88ee3b..e6941c9f6ed6 100644 --- a/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -38,7 +38,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" #include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/DataBufferLLVM.h" +#include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" @@ -862,8 +862,7 @@ ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp, lldb::offset_t file_offset, lldb::offset_t length) { if (!data_sp) { - data_sp = - DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset); + data_sp = MapFileData(*file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; @@ -874,8 +873,7 @@ ObjectFile *ObjectFileMachO::CreateInstance(const lldb::ModuleSP &module_sp, // Update the data to contain the entire file if it doesn't already if (data_sp->GetByteSize() < length) { - data_sp = - DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset); + data_sp = MapFileData(*file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; @@ -914,8 +912,7 @@ size_t ObjectFileMachO::GetModuleSpecifications( size_t header_and_load_cmds = header.sizeofcmds + MachHeaderSizeFromMagic(header.magic); if (header_and_load_cmds >= data_sp->GetByteSize()) { - data_sp = DataBufferLLVM::CreateSliceFromPath( - file.GetPath(), header_and_load_cmds, file_offset); + data_sp = MapFileData(file, header_and_load_cmds, file_offset); data.SetData(data_sp); data_offset = MachHeaderSizeFromMagic(header.magic); } @@ -1127,8 +1124,7 @@ bool ObjectFileMachO::ParseHeader() { ReadMemory(process_sp, m_memory_addr, header_and_lc_size); } else { // Read in all only the load command data from the file on disk - data_sp = DataBufferLLVM::CreateSliceFromPath( - m_file.GetPath(), header_and_lc_size, m_file_offset); + data_sp = MapFileData(m_file, header_and_lc_size, m_file_offset); if (data_sp->GetByteSize() != header_and_lc_size) return false; } @@ -2100,9 +2096,8 @@ UUID ObjectFileMachO::GetSharedCacheUUID(FileSpec dyld_shared_cache, const ByteOrder byte_order, const uint32_t addr_byte_size) { UUID dsc_uuid; - DataBufferSP DscData = DataBufferLLVM::CreateSliceFromPath( - dyld_shared_cache.GetPath(), - sizeof(struct lldb_copy_dyld_cache_header_v1), 0); + DataBufferSP DscData = MapFileData( + dyld_shared_cache, sizeof(struct lldb_copy_dyld_cache_header_v1), 0); if (!DscData) return dsc_uuid; DataExtractor dsc_header_data(DscData, byte_order, addr_byte_size); @@ -2708,9 +2703,8 @@ size_t ObjectFileMachO::ParseSymtab() { // Process the dyld shared cache header to find the unmapped symbols - DataBufferSP dsc_data_sp = DataBufferLLVM::CreateSliceFromPath( - dsc_filespec.GetPath(), sizeof(struct lldb_copy_dyld_cache_header_v1), - 0); + DataBufferSP dsc_data_sp = MapFileData( + dsc_filespec, sizeof(struct lldb_copy_dyld_cache_header_v1), 0); if (!dsc_uuid.IsValid()) { dsc_uuid = GetSharedCacheUUID(dsc_filespec, byte_order, addr_byte_size); } @@ -2742,11 +2736,9 @@ size_t ObjectFileMachO::ParseSymtab() { if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)) { - DataBufferSP dsc_mapping_info_data_sp = - DataBufferLLVM::CreateSliceFromPath( - dsc_filespec.GetPath(), - sizeof(struct lldb_copy_dyld_cache_mapping_info), - mappingOffset); + DataBufferSP dsc_mapping_info_data_sp = MapFileData( + dsc_filespec, sizeof(struct lldb_copy_dyld_cache_mapping_info), + mappingOffset); DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size); @@ -2770,9 +2762,7 @@ size_t ObjectFileMachO::ParseSymtab() { if (localSymbolsOffset && localSymbolsSize) { // Map the local symbols DataBufferSP dsc_local_symbols_data_sp = - DataBufferLLVM::CreateSliceFromPath(dsc_filespec.GetPath(), - localSymbolsSize, - localSymbolsOffset); + MapFileData(dsc_filespec, localSymbolsSize, localSymbolsOffset); if (dsc_local_symbols_data_sp) { DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, diff --git a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 72b1b15f08f8..77bfa7fe0a64 100644 --- a/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -22,7 +22,6 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" @@ -66,8 +65,7 @@ ObjectFile *ObjectFilePECOFF::CreateInstance(const lldb::ModuleSP &module_sp, lldb::offset_t file_offset, lldb::offset_t length) { if (!data_sp) { - data_sp = - DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset); + data_sp = MapFileData(file, length, file_offset); if (!data_sp) return nullptr; data_offset = 0; @@ -78,8 +76,7 @@ ObjectFile *ObjectFilePECOFF::CreateInstance(const lldb::ModuleSP &module_sp, // Update the data to contain the entire file if it doesn't already if (data_sp->GetByteSize() < length) { - data_sp = - DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset); + data_sp = MapFileData(file, length, file_offset); if (!data_sp) return nullptr; } @@ -436,8 +433,7 @@ DataExtractor ObjectFilePECOFF::ReadImageData(uint32_t offset, size_t size) { if (m_file) { // A bit of a hack, but we intend to write to this buffer, so we can't // mmap it. - auto buffer_sp = - DataBufferLLVM::CreateSliceFromPath(m_file.GetPath(), size, offset, true); + auto buffer_sp = MapFileData(m_file, size, offset); return DataExtractor(buffer_sp, GetByteOrder(), GetAddressByteSize()); } ProcessSP process_sp(m_process_wp.lock()); diff --git a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index b39aa103f1db..b04d72f755f6 100644 --- a/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1173,7 +1173,7 @@ const char *PlatformDarwin::GetDeveloperDirectory() { xcode_dir_path.append("/usr/share/xcode-select/xcode_dir_path"); temp_file_spec.SetFile(xcode_dir_path, false); auto dir_buffer = - DataBufferLLVM::CreateFromPath(temp_file_spec.GetPath(), true); + DataBufferLLVM::CreateFromPath(temp_file_spec.GetPath()); if (dir_buffer && dir_buffer->GetByteSize() > 0) { llvm::StringRef path_ref(dir_buffer->GetChars()); // Trim tailing newlines and make sure there is enough room for a null diff --git a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp index 46d522531a5b..3d9f498b1e9a 100644 --- a/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp +++ b/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp @@ -98,7 +98,7 @@ bool CommunicationKDP::SendRequestAndGetReply( #ifdef LLDB_CONFIGURATION_DEBUG // NOTE: this only works for packets that are in native endian byte order assert(request_packet.GetSize() == - *((uint16_t *)(request_packet.GetData() + 2))); + *((const uint16_t *)(request_packet.GetData() + 2))); #endif lldb::offset_t offset = 1; const uint32_t num_retries = 3; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp index 1e20a090161d..4d4a4f8c5c7a 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -60,6 +60,7 @@ StateType GDBRemoteClientBase::SendContinuePacketAndWaitForResponse( continue; if (steady_clock::now() >= m_interrupt_time + kInterruptTimeout) return eStateInvalid; + break; } case PacketResult::Success: break; diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 6ae2b225d869..54b12cfb3b8c 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1743,8 +1743,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, "DWARF DW_TAG_array_type DIE at 0x%8.8x has a " "class/union/struct element type DIE 0x%8.8x that is a " "forward declaration, not a complete definition.\nTry " - "compiling the source file with -fno-limit-debug-info or " - "disable -gmodule", + "compiling the source file with -fstandalone-debug or " + "disable -gmodules", die.GetOffset(), type_die_ref.die_offset); else module_sp->ReportError( @@ -2255,7 +2255,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, if (die.GetCU()->GetProducer() == DWARFCompileUnit::eProducerClang) module->ReportError(":: Try compiling the source file with " - "-fno-limit-debug-info."); + "-fstandalone-debug."); // We have no choice other than to pretend that the base class // is complete. If we don't do this, clang will crash when we @@ -3095,7 +3095,7 @@ bool DWARFASTParserClang::ParseChildMembers( "DWARF DIE at 0x%8.8x (class %s) has a member variable " "0x%8.8x (%s) whose type is a forward declaration, not a " "complete definition.\nTry compiling the source file " - "with -fno-limit-debug-info", + "with -fstandalone-debug", parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(), name); else diff --git a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 9b98ebe112a2..7802d6f0d859 100644 --- a/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -124,6 +124,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { } else if (auto type_def = llvm::dyn_cast(&type)) { lldb_private::Type *target_type = m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId()); + if (!target_type) + return nullptr; std::string name = type_def->getName(); uint64_t bytes = type_def->getLength(); if (!target_type) @@ -179,6 +181,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { lldb_private::Type *element_type = m_ast.GetSymbolFile()->ResolveTypeUID(element_uid); + if (!element_type) + return nullptr; CompilerType element_ast_type = element_type->GetFullCompilerType(); CompilerType array_ast_type = m_ast.CreateArrayType(element_ast_type, num_elements, false); diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 5e713224fcf8..de9b9f024fc7 100644 --- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -19,14 +19,18 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/TypeMap.h" +#include "lldb/Utility/RegularExpression.h" #include "llvm/DebugInfo/PDB/GenericError.h" +#include "llvm/DebugInfo/PDB/IPDBDataStream.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" +#include "llvm/DebugInfo/PDB/IPDBTable.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h" #include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h" +#include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" @@ -93,6 +97,10 @@ SymbolFilePDB::SymbolFilePDB(lldb_private::ObjectFile *object_file) SymbolFilePDB::~SymbolFilePDB() {} uint32_t SymbolFilePDB::CalculateAbilities() { + uint32_t abilities = 0; + if (!m_obj_file) + return 0; + if (!m_session_up) { // Lazily load and match the PDB file, but only do this once. std::string exePath = m_obj_file->GetFileSpec().GetPath(); @@ -100,10 +108,46 @@ uint32_t SymbolFilePDB::CalculateAbilities() { m_session_up); if (error) { llvm::consumeError(std::move(error)); - return 0; + auto module_sp = m_obj_file->GetModule(); + if (!module_sp) + return 0; + // See if any symbol file is specified through `--symfile` option. + FileSpec symfile = module_sp->GetSymbolFileFileSpec(); + if (!symfile) + return 0; + error = loadDataForPDB(PDB_ReaderType::DIA, + llvm::StringRef(symfile.GetPath()), + m_session_up); + if (error) { + llvm::consumeError(std::move(error)); + return 0; + } } } - return CompileUnits | LineTables; + if (!m_session_up.get()) + return 0; + + auto enum_tables_up = m_session_up->getEnumTables(); + if (!enum_tables_up) + return 0; + while (auto table_up = enum_tables_up->getNext()) { + if (table_up->getItemCount() == 0) + continue; + auto type = table_up->getTableType(); + switch (type) { + case PDB_TableType::Symbols: + // This table represents a store of symbols with types listed in + // PDBSym_Type + abilities |= (CompileUnits | Functions | Blocks | + GlobalVariables | LocalVariables | VariableTypes); + break; + case PDB_TableType::LineNumbers: + abilities |= LineTables; + break; + default: break; + } + } + return abilities; } void SymbolFilePDB::InitializeObject() { @@ -250,7 +294,8 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { return nullptr; lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type); - m_types.insert(std::make_pair(type_uid, result)); + if (result.get()) + m_types.insert(std::make_pair(type_uid, result)); return result.get(); } @@ -385,19 +430,16 @@ uint32_t SymbolFilePDB::FindTypes( std::string name_str = name.AsCString(); - // If this might be a regex, we have to return EVERY symbol and process them - // one by one, which is going to destroy performance on large PDB files. So - // try really hard not to use a regex match. - if (name_str.find_first_of("[]?*.-+\\") != std::string::npos) - FindTypesByRegex(name_str, max_matches, types); - else - FindTypesByName(name_str, max_matches, types); + // There is an assumption 'name' is not a regex + FindTypesByName(name_str, max_matches, types); + return types.GetSize(); } -void SymbolFilePDB::FindTypesByRegex(const std::string ®ex, - uint32_t max_matches, - lldb_private::TypeMap &types) { +void +SymbolFilePDB::FindTypesByRegex(const lldb_private::RegularExpression ®ex, + uint32_t max_matches, + lldb_private::TypeMap &types) { // When searching by regex, we need to go out of our way to limit the search // space as much as possible since this searches EVERYTHING in the PDB, // manually doing regex comparisons. PDB library isn't optimized for regex @@ -409,8 +451,6 @@ void SymbolFilePDB::FindTypesByRegex(const std::string ®ex, auto global = m_session_up->getGlobalScope(); std::unique_ptr results; - std::regex re(regex); - uint32_t matches = 0; for (auto tag : tags_to_search) { @@ -433,7 +473,7 @@ void SymbolFilePDB::FindTypesByRegex(const std::string ®ex, continue; } - if (!std::regex_match(type_name, re)) + if (!regex.Execute(type_name)) continue; // This should cause the type to get cached and stored in the `m_types` diff --git a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index efd2cb081dca..d78358c714ac 100644 --- a/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -172,7 +172,8 @@ class SymbolFilePDB : public lldb_private::SymbolFile { const llvm::pdb::PDBSymbolCompiland &cu, llvm::DenseMap &index_map) const; - void FindTypesByRegex(const std::string ®ex, uint32_t max_matches, + void FindTypesByRegex(const lldb_private::RegularExpression ®ex, + uint32_t max_matches, lldb_private::TypeMap &types); void FindTypesByName(const std::string &name, uint32_t max_matches, diff --git a/source/Symbol/ObjectFile.cpp b/source/Symbol/ObjectFile.cpp index 7d73cb19d508..2129a4463cdd 100644 --- a/source/Symbol/ObjectFile.cpp +++ b/source/Symbol/ObjectFile.cpp @@ -688,3 +688,8 @@ Status ObjectFile::LoadInMemory(Target &target, bool set_pc) { void ObjectFile::RelocateSection(lldb_private::Section *section) { } + +DataBufferSP ObjectFile::MapFileData(const FileSpec &file, uint64_t Size, + uint64_t Offset) { + return DataBufferLLVM::CreateSliceFromPath(file.GetPath(), Size, Offset); +} diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp index 903f50887fec..fdc10cf48275 100644 --- a/source/Target/Target.cpp +++ b/source/Target/Target.cpp @@ -2313,7 +2313,7 @@ ExpressionResults Target::EvaluateExpression( result_valobj_sp = persistent_var_sp->GetValueObject(); execution_results = eExpressionCompleted; } else { - const char *prefix = GetExpressionPrefixContentsAsCString(); + llvm::StringRef prefix = GetExpressionPrefixContents(); Status error; execution_results = UserExpression::Evaluate(exe_ctx, options, expr, prefix, result_valobj_sp, error, @@ -4046,18 +4046,19 @@ LanguageType TargetProperties::GetLanguage() const { return LanguageType(); } -const char *TargetProperties::GetExpressionPrefixContentsAsCString() { +llvm::StringRef TargetProperties::GetExpressionPrefixContents() { const uint32_t idx = ePropertyExprPrefix; OptionValueFileSpec *file = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false, idx); if (file) { - const bool null_terminate = true; - DataBufferSP data_sp(file->GetFileContents(null_terminate)); + DataBufferSP data_sp(file->GetFileContents()); if (data_sp) - return (const char *)data_sp->GetBytes(); + return llvm::StringRef( + reinterpret_cast(data_sp->GetBytes()), + data_sp->GetByteSize()); } - return nullptr; + return ""; } bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() { diff --git a/source/Utility/DataBufferLLVM.cpp b/source/Utility/DataBufferLLVM.cpp index bebcafbf9150..713c3c2814ea 100644 --- a/source/Utility/DataBufferLLVM.cpp +++ b/source/Utility/DataBufferLLVM.cpp @@ -18,7 +18,8 @@ using namespace lldb_private; -DataBufferLLVM::DataBufferLLVM(std::unique_ptr MemBuffer) +DataBufferLLVM::DataBufferLLVM( + std::unique_ptr MemBuffer) : Buffer(std::move(MemBuffer)) { assert(Buffer != nullptr && "Cannot construct a DataBufferLLVM with a null buffer"); @@ -28,13 +29,13 @@ DataBufferLLVM::~DataBufferLLVM() {} std::shared_ptr DataBufferLLVM::CreateSliceFromPath(const llvm::Twine &Path, uint64_t Size, - uint64_t Offset, bool Private) { + uint64_t Offset) { // If the file resides non-locally, pass the volatile flag so that we don't // mmap it. - if (!Private) - Private = !llvm::sys::fs::is_local(Path); + bool IsVolatile = !llvm::sys::fs::is_local(Path); - auto Buffer = llvm::MemoryBuffer::getFileSlice(Path, Size, Offset, Private); + auto Buffer = + llvm::WritableMemoryBuffer::getFileSlice(Path, Size, Offset, IsVolatile); if (!Buffer) return nullptr; return std::shared_ptr( @@ -42,13 +43,12 @@ DataBufferLLVM::CreateSliceFromPath(const llvm::Twine &Path, uint64_t Size, } std::shared_ptr -DataBufferLLVM::CreateFromPath(const llvm::Twine &Path, bool NullTerminate, bool Private) { +DataBufferLLVM::CreateFromPath(const llvm::Twine &Path) { // If the file resides non-locally, pass the volatile flag so that we don't // mmap it. - if (!Private) - Private = !llvm::sys::fs::is_local(Path); + bool IsVolatile = !llvm::sys::fs::is_local(Path); - auto Buffer = llvm::MemoryBuffer::getFile(Path, -1, NullTerminate, Private); + auto Buffer = llvm::WritableMemoryBuffer::getFile(Path, -1, IsVolatile); if (!Buffer) return nullptr; return std::shared_ptr( @@ -56,15 +56,13 @@ DataBufferLLVM::CreateFromPath(const llvm::Twine &Path, bool NullTerminate, bool } uint8_t *DataBufferLLVM::GetBytes() { - return const_cast(GetBuffer()); + return reinterpret_cast(Buffer->getBufferStart()); } -const uint8_t *DataBufferLLVM::GetBytes() const { return GetBuffer(); } +const uint8_t *DataBufferLLVM::GetBytes() const { + return reinterpret_cast(Buffer->getBufferStart()); +} lldb::offset_t DataBufferLLVM::GetByteSize() const { return Buffer->getBufferSize(); } - -const uint8_t *DataBufferLLVM::GetBuffer() const { - return reinterpret_cast(Buffer->getBufferStart()); -} diff --git a/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/tools/debugserver/debugserver.xcodeproj/project.pbxproj index d97b438ce8e5..6a919cfef5de 100644 --- a/tools/debugserver/debugserver.xcodeproj/project.pbxproj +++ b/tools/debugserver/debugserver.xcodeproj/project.pbxproj @@ -820,7 +820,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; @@ -920,8 +920,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; @@ -1020,8 +1019,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; @@ -1127,8 +1125,7 @@ CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -1209,8 +1206,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; @@ -1279,8 +1275,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; @@ -1352,7 +1347,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; @@ -1460,8 +1455,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; @@ -1601,8 +1595,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; @@ -1699,8 +1692,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; @@ -1823,8 +1815,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; @@ -1955,8 +1946,7 @@ buildSettings = { CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; CLANG_CXX_LIBRARY = "libc++"; - "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-macosx-entitlements.plist"; - "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist"; + "CODE_SIGN_ENTITLEMENTS[sdk=*]" = "source/debugserver-entitlements.plist"; "CODE_SIGN_ENTITLEMENTS[sdk=macosx*]" = "source/debugserver-macosx-entitlements.plist"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=macosx*]" = ""; diff --git a/tools/debugserver/source/RNBContext.cpp b/tools/debugserver/source/RNBContext.cpp index c1319af02322..c86511c6e226 100644 --- a/tools/debugserver/source/RNBContext.cpp +++ b/tools/debugserver/source/RNBContext.cpp @@ -42,6 +42,25 @@ const char *RNBContext::EnvironmentAtIndex(size_t index) { return NULL; } +static std::string GetEnvironmentKey(const std::string &env) { + std::string key = env.substr(0, env.find('=')); + if (!key.empty() && key.back() == '=') + key.pop_back(); + return key; +} + +void RNBContext::PushEnvironmentIfNeeded(const char *arg) { + if (!arg) + return; + std::string arg_key = GetEnvironmentKey(arg); + + for (const std::string &entry: m_env_vec) { + if (arg_key == GetEnvironmentKey(entry)) + return; + } + m_env_vec.push_back(arg); +} + const char *RNBContext::ArgumentAtIndex(size_t index) { if (index < m_arg_vec.size()) return m_arg_vec[index].c_str(); diff --git a/tools/debugserver/source/RNBContext.h b/tools/debugserver/source/RNBContext.h index 6fe7a299573a..0c649ae41007 100644 --- a/tools/debugserver/source/RNBContext.h +++ b/tools/debugserver/source/RNBContext.h @@ -86,6 +86,7 @@ class RNBContext { if (arg) m_env_vec.push_back(arg); } + void PushEnvironmentIfNeeded(const char *arg); void ClearEnvironment() { m_env_vec.erase(m_env_vec.begin(), m_env_vec.end()); } diff --git a/tools/debugserver/source/debugserver.cpp b/tools/debugserver/source/debugserver.cpp index 8291f8d32b51..7ae321ba431b 100644 --- a/tools/debugserver/source/debugserver.cpp +++ b/tools/debugserver/source/debugserver.cpp @@ -1020,6 +1020,7 @@ int main(int argc, char *argv[]) { optind = 1; #endif + bool forward_env = false; while ((ch = getopt_long_only(argc, argv, short_options, g_long_options, &long_option_index)) != -1) { DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n", ch, (uint8_t)ch, @@ -1251,14 +1252,7 @@ int main(int argc, char *argv[]) { break; case 'F': - // Pass the current environment down to the process that gets launched - { - char **host_env = *_NSGetEnviron(); - char *env_entry; - size_t i; - for (i = 0; (env_entry = host_env[i]) != NULL; ++i) - remote->Context().PushEnvironment(env_entry); - } + forward_env = true; break; case '2': @@ -1420,6 +1414,18 @@ int main(int argc, char *argv[]) { if (start_mode == eRNBRunLoopModeExit) return -1; + if (forward_env || start_mode == eRNBRunLoopModeInferiorLaunching) { + // Pass the current environment down to the process that gets launched + // This happens automatically in the "launching" mode. For the rest, we + // only do that if the user explicitly requested this via --forward-env + // argument. + char **host_env = *_NSGetEnviron(); + char *env_entry; + size_t i; + for (i = 0; (env_entry = host_env[i]) != NULL; ++i) + remote->Context().PushEnvironmentIfNeeded(env_entry); + } + RNBRunLoopMode mode = start_mode; char err_str[1024] = {'\0'}; diff --git a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp index 561fa91a0ee3..dceb29f5908f 100644 --- a/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp +++ b/tools/lldb-mi/MICmnLLDBDebuggerHandleEvents.cpp @@ -18,6 +18,7 @@ #include "lldb/API/SBTarget.h" #include "lldb/API/SBThread.h" #include "lldb/API/SBUnixSignals.h" +#include "llvm/Support/Compiler.h" #ifdef _WIN32 #include // For the ::_access() #else @@ -899,6 +900,7 @@ bool CMICmnLLDBDebuggerHandleEvents::HandleProcessEventBroadcastBitStateChanged( bOk = HandleProcessEventStateStopped(vEvent, bShouldBrk); if (bShouldBrk) break; + LLVM_FALLTHROUGH; case lldb::eStateCrashed: case lldb::eStateSuspended: pEventType = "eStateSuspended"; diff --git a/tools/lldb-mi/MIUtilString.cpp b/tools/lldb-mi/MIUtilString.cpp index 45196a70398d..3797d1001798 100644 --- a/tools/lldb-mi/MIUtilString.cpp +++ b/tools/lldb-mi/MIUtilString.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// // Third party headers +#include "llvm/Support/Compiler.h" #include #include // for PRIx8 #include // for ULONG_MAX @@ -890,7 +891,7 @@ CMIUtilString CMIUtilString::ConvertToPrintableASCII(const char vChar, case '"': if (bEscapeQuotes) return "\\\""; - // fall thru + LLVM_FALLTHROUGH; default: if (::isprint(vChar)) return Format("%c", vChar); @@ -924,7 +925,7 @@ CMIUtilString::ConvertCharValueToPrintableASCII(char vChar, case '"': if (bEscapeQuotes) return "\\\""; - // fall thru + LLVM_FALLTHROUGH; default: if (::isprint(vChar)) return Format("%c", vChar); diff --git a/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp b/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp index 1e9cf1700642..ac4eba1197ab 100644 --- a/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ b/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -154,8 +154,7 @@ TEST_F(SymbolFilePDBTests, TestAbilitiesForPDB) { EXPECT_NE(nullptr, symfile); EXPECT_EQ(symfile->GetPluginName(), SymbolFilePDB::GetPluginNameStatic()); - uint32_t expected_abilities = - SymbolFile::CompileUnits | SymbolFile::LineTables; + uint32_t expected_abilities = SymbolFile::kAllAbilities; EXPECT_EQ(expected_abilities, symfile->CalculateAbilities()); } @@ -520,6 +519,13 @@ TEST_F(SymbolFilePDBTests, TestRegexNameMatch) { false, 0, searched_files, results); EXPECT_GT(num_results, 1u); EXPECT_EQ(num_results, results.GetSize()); + + // We expect no exception thrown if the given regex can't be compiled + results.Clear(); + num_results = symfile->FindTypes(sc, ConstString("**"), nullptr, + false, 0, searched_files, results); + EXPECT_EQ(num_results, 0u); + EXPECT_EQ(num_results, results.GetSize()); } TEST_F(SymbolFilePDBTests, TestMaxMatches) { diff --git a/unittests/tools/lldb-server/CMakeLists.txt b/unittests/tools/lldb-server/CMakeLists.txt index 8641e8ddb5c9..14df6e64b2ac 100644 --- a/unittests/tools/lldb-server/CMakeLists.txt +++ b/unittests/tools/lldb-server/CMakeLists.txt @@ -13,9 +13,9 @@ add_lldb_test_executable(thread_inferior inferior/thread_inferior.cpp) add_lldb_test_executable(environment_check inferior/environment_check.cpp) if (CMAKE_SYSTEM_NAME MATCHES "Darwin") - add_definitions(-DLLDB_SERVER="$") + add_definitions(-DLLDB_SERVER="$" -DLLDB_SERVER_IS_DEBUGSERVER=1) else() - add_definitions(-DLLDB_SERVER="$") + add_definitions(-DLLDB_SERVER="$" -DLLDB_SERVER_IS_DEBUGSERVER=0) endif() add_definitions( diff --git a/unittests/tools/lldb-server/tests/LLGSTest.cpp b/unittests/tools/lldb-server/tests/LLGSTest.cpp index 75d964ed26f4..8733adefa389 100644 --- a/unittests/tools/lldb-server/tests/LLGSTest.cpp +++ b/unittests/tools/lldb-server/tests/LLGSTest.cpp @@ -16,11 +16,6 @@ using namespace lldb_private; using namespace llvm; TEST_F(TestBase, LaunchModePreservesEnvironment) { - if (TestClient::IsDebugServer()) { - GTEST_LOG_(WARNING) << "Test fails with debugserver: llvm.org/pr35671"; - return; - } - putenv(const_cast("LLDB_TEST_MAGIC_VARIABLE=LLDB_TEST_MAGIC_VALUE")); auto ClientOr = TestClient::launch(getLogFileName(), @@ -34,3 +29,20 @@ TEST_F(TestBase, LaunchModePreservesEnvironment) { HasValue(testing::Property(&StopReply::getKind, WaitStatus{WaitStatus::Exit, 0}))); } + +TEST_F(TestBase, DS_TEST(DebugserverEnv)) { + // Test that --env takes precedence over inherited environment variables. + putenv(const_cast("LLDB_TEST_MAGIC_VARIABLE=foobar")); + + auto ClientOr = TestClient::launchCustom(getLogFileName(), + { "--env", "LLDB_TEST_MAGIC_VARIABLE=LLDB_TEST_MAGIC_VALUE" }, + {getInferiorPath("environment_check")}); + ASSERT_THAT_EXPECTED(ClientOr, Succeeded()); + auto &Client = **ClientOr; + + ASSERT_THAT_ERROR(Client.ContinueAll(), Succeeded()); + ASSERT_THAT_EXPECTED( + Client.GetLatestStopReplyAs(), + HasValue(testing::Property(&StopReply::getKind, + WaitStatus{WaitStatus::Exit, 0}))); +} diff --git a/unittests/tools/lldb-server/tests/TestClient.cpp b/unittests/tools/lldb-server/tests/TestClient.cpp index 773466abe855..4653c2df1ce9 100644 --- a/unittests/tools/lldb-server/tests/TestClient.cpp +++ b/unittests/tools/lldb-server/tests/TestClient.cpp @@ -27,11 +27,6 @@ using namespace lldb_private; using namespace llvm; namespace llgs_tests { -bool TestClient::IsDebugServer() { - return sys::path::filename(LLDB_SERVER).contains("debugserver"); -} - -bool TestClient::IsLldbServer() { return !IsDebugServer(); } TestClient::TestClient(std::unique_ptr Conn) { SetConnection(Conn.release()); @@ -56,6 +51,10 @@ Expected> TestClient::launch(StringRef Log) { } Expected> TestClient::launch(StringRef Log, ArrayRef InferiorArgs) { + return launchCustom(Log, {}, InferiorArgs); +} + +Expected> TestClient::launchCustom(StringRef Log, ArrayRef ServerArgs, ArrayRef InferiorArgs) { const ArchSpec &arch_spec = HostInfo::GetArchitecture(); Args args; args.AppendArgument(LLDB_SERVER); @@ -80,6 +79,9 @@ Expected> TestClient::launch(StringRef Log, ArrayRef args.AppendArgument( ("localhost:" + Twine(listen_socket.GetLocalPortNumber())).str()); + for (StringRef arg : ServerArgs) + args.AppendArgument(arg); + if (!InferiorArgs.empty()) { args.AppendArgument("--"); for (StringRef arg : InferiorArgs) diff --git a/unittests/tools/lldb-server/tests/TestClient.h b/unittests/tools/lldb-server/tests/TestClient.h index 4fa1bbb8ac93..b5195307876d 100644 --- a/unittests/tools/lldb-server/tests/TestClient.h +++ b/unittests/tools/lldb-server/tests/TestClient.h @@ -21,12 +21,20 @@ #include #include +#if LLDB_SERVER_IS_DEBUGSERVER +#define LLGS_TEST(x) DISABLED_ ## x +#define DS_TEST(x) x +#else +#define LLGS_TEST(x) x +#define DS_TEST(x) DISABLED_ ## x +#endif + namespace llgs_tests { class TestClient : public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient { public: - static bool IsDebugServer(); - static bool IsLldbServer(); + static bool IsDebugServer() { return LLDB_SERVER_IS_DEBUGSERVER; } + static bool IsLldbServer() { return !IsDebugServer(); } /// Launches the server, connects it to the client and returns the client. If /// Log is non-empty, the server will write it's log to this file. @@ -37,6 +45,13 @@ class TestClient static llvm::Expected> launch(llvm::StringRef Log, llvm::ArrayRef InferiorArgs); + /// Allows user to pass additional arguments to the server. Be careful when + /// using this for generic tests, as the two stubs have different + /// command-line interfaces. + static llvm::Expected> + launchCustom(llvm::StringRef Log, llvm::ArrayRef ServerArgs, llvm::ArrayRef InferiorArgs); + + ~TestClient() override; llvm::Error SetInferior(llvm::ArrayRef inferior_args); llvm::Error ListThreadsInStopReply();