aboutsummaryrefslogtreecommitdiff
path: root/lldb
diff options
context:
space:
mode:
Diffstat (limited to 'lldb')
-rw-r--r--lldb/cmake/modules/LLDBFramework.cmake2
-rw-r--r--lldb/include/lldb/lldb-enumerations.h2
-rw-r--r--lldb/packages/Python/lldbsuite/test/dotest.py2
-rw-r--r--lldb/packages/Python/lldbsuite/test/lldbtest.py2
-rw-r--r--lldb/source/Expression/IRExecutionUnit.cpp8
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp4
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h1
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt1
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp11
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxx.h4
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxProxyArray.cpp194
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp4
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp79
-rw-r--r--lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp6
-rw-r--r--lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py3
-rw-r--r--lldb/test/API/commands/process/detach-resumes/Makefile4
-rw-r--r--lldb/test/API/commands/process/detach-resumes/TestDetachResumes.py59
-rw-r--r--lldb/test/API/commands/process/detach-resumes/main.cpp48
-rw-r--r--lldb/test/API/functionalities/asan/Makefile6
-rw-r--r--lldb/test/API/functionalities/asan/TestMemoryHistory.py74
-rw-r--r--lldb/test/API/functionalities/asan/TestReportData.py21
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py88
-rw-r--r--lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp6
-rw-r--r--lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py16
-rw-r--r--lldb/test/Shell/lit.cfg.py12
-rw-r--r--lldb/test/Shell/lit.site.cfg.py.in1
-rw-r--r--lldb/unittests/UnwindAssembly/CMakeLists.txt4
-rw-r--r--lldb/unittests/UnwindAssembly/x86-but-no-x86-target/CMakeLists.txt10
-rw-r--r--lldb/unittests/UnwindAssembly/x86-but-no-x86-target/Testx86AssemblyInspectionEngine.cpp103
-rw-r--r--lldb/unittests/tools/CMakeLists.txt4
30 files changed, 659 insertions, 120 deletions
diff --git a/lldb/cmake/modules/LLDBFramework.cmake b/lldb/cmake/modules/LLDBFramework.cmake
index 81fc596..f915839 100644
--- a/lldb/cmake/modules/LLDBFramework.cmake
+++ b/lldb/cmake/modules/LLDBFramework.cmake
@@ -119,7 +119,7 @@ add_custom_command(TARGET liblldb POST_BUILD
if(NOT APPLE_EMBEDDED)
if (TARGET clang-resource-headers)
add_dependencies(liblldb clang-resource-headers)
- set(clang_resource_headers_dir $<TARGET_PROPERTY:clang-resource-headers,RUNTIME_OUTPUT_DIRECTORY>)
+ set(clang_resource_headers_dir $<TARGET_PROPERTY:clang-resource-headers,INTERFACE_INCLUDE_DIRECTORIES>)
else()
set(clang_resource_headers_dir ${LLDB_EXTERNAL_CLANG_RESOURCE_DIR}/include)
if(NOT EXISTS ${clang_resource_headers_dir})
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index f3b07ea..15e4585 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -1310,7 +1310,7 @@ enum CompletionType {
/// Specifies if children need to be re-computed
/// after a call to \ref SyntheticChildrenFrontEnd::Update.
-enum class ChildCacheState {
+enum ChildCacheState {
eRefetch = 0, ///< Children need to be recomputed dynamically.
eReuse = 1, ///< Children did not change and don't need to be recomputed;
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index 8c29145..2ec4a84 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -248,7 +248,7 @@ def parseOptionsAndInitTestdirs():
configuration.compiler = which(args.compiler)
if not is_exe(configuration.compiler):
logging.error(
- "%s is not a valid compiler executable; aborting...", args.compiler
+ '"%s" is not a valid compiler executable; aborting...', args.compiler
)
sys.exit(-1)
else:
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index c28a78a..7a7afec 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -751,6 +751,8 @@ class Base(unittest.TestCase):
"settings set symbols.enable-external-lookup false",
# Inherit the TCC permissions from the inferior's parent.
"settings set target.inherit-tcc true",
+ # Based on https://discourse.llvm.org/t/running-lldb-in-a-container/76801/4
+ "settings set target.disable-aslr false",
# Kill rather than detach from the inferior if something goes wrong.
"settings set target.detach-on-error false",
# Disable fix-its by default so that incorrect expressions in tests don't
diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp
index cb9bee8..7ad0e5f 100644
--- a/lldb/source/Expression/IRExecutionUnit.cpp
+++ b/lldb/source/Expression/IRExecutionUnit.cpp
@@ -13,6 +13,7 @@
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/CodeGen.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
@@ -279,10 +280,13 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
llvm::EngineBuilder builder(std::move(m_module_up));
llvm::Triple triple(m_module->getTargetTriple());
+ // PIC needed for ELF to avoid generating 32-bit relocations (which overflow
+ // if the object is loaded into high memory).
+ bool want_pic = triple.isOSBinFormatMachO() || triple.isOSBinFormatELF();
+
builder.setEngineKind(llvm::EngineKind::JIT)
.setErrorStr(&error_string)
- .setRelocationModel(triple.isOSBinFormatMachO() ? llvm::Reloc::PIC_
- : llvm::Reloc::Static)
+ .setRelocationModel(want_pic ? llvm::Reloc::PIC_ : llvm::Reloc::Static)
.setMCJITMemoryManager(std::make_unique<MemoryManager>(*this))
.setOptLevel(llvm::CodeGenOptLevel::Less);
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 2d306b4..31f6447 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -1049,7 +1049,6 @@ void ClangExpressionDeclMap::LookupInModulesDeclVendor(
context.AddNamedDecl(copied_function);
context.m_found_function_with_type_info = true;
- context.m_found_function = true;
} else if (auto copied_var = dyn_cast<clang::VarDecl>(copied_decl)) {
context.AddNamedDecl(copied_var);
context.m_found_variable = true;
@@ -1299,7 +1298,6 @@ void ClangExpressionDeclMap::LookupFunction(
AddOneFunction(context, sym_ctx.function, nullptr);
context.m_found_function_with_type_info = true;
- context.m_found_function = true;
} else if (sym_ctx.symbol) {
Symbol *symbol = sym_ctx.symbol;
if (target && symbol->GetType() == eSymbolTypeReExported) {
@@ -1331,10 +1329,8 @@ void ClangExpressionDeclMap::LookupFunction(
if (!context.m_found_function_with_type_info) {
if (extern_symbol) {
AddOneFunction(context, nullptr, extern_symbol);
- context.m_found_function = true;
} else if (non_extern_symbol) {
AddOneFunction(context, nullptr, non_extern_symbol);
- context.m_found_function = true;
}
}
}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
index dc8621dd..9a33206 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.h
@@ -41,7 +41,6 @@ struct NameSearchContext {
bool m_found_variable = false;
bool m_found_function_with_type_info = false;
- bool m_found_function = false;
bool m_found_local_vars_nsp = false;
bool m_found_type = false;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 0c6fdb2..f59032c 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -14,6 +14,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
LibCxxQueue.cpp
LibCxxRangesRefView.cpp
LibCxxSliceArray.cpp
+ LibCxxProxyArray.cpp
LibCxxSpan.cpp
LibCxxTuple.cpp
LibCxxUnorderedMap.cpp
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index afb683f..5f06841 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -762,6 +762,12 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"^std::__[[:alnum:]]+::slice_array<.+>$", stl_deref_flags, true);
AddCXXSynthetic(
cpp_category_sp,
+ lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEndCreator,
+ "libc++ synthetic children for the valarray proxy arrays",
+ "^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$",
+ stl_deref_flags, true);
+ AddCXXSynthetic(
+ cpp_category_sp,
lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator,
"libc++ std::forward_list synthetic children",
"^std::__[[:alnum:]]+::forward_list<.+>$", stl_synth_flags, true);
@@ -890,6 +896,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::slice_array summary provider",
"^std::__[[:alnum:]]+::slice_array<.+>$", stl_summary_flags,
true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ summary provider for the valarray proxy arrays",
+ "^std::__[[:alnum:]]+::(gslice|mask|indirect)_array<.+>$",
+ stl_summary_flags, true);
AddCXXSummary(
cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::list summary provider",
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
index 8e97174..7fe15d1 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h
@@ -232,6 +232,10 @@ LibcxxStdSliceArraySyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
SyntheticChildrenFrontEnd *
+LibcxxStdProxyArraySyntheticFrontEndCreator(CXXSyntheticChildren *,
+ lldb::ValueObjectSP);
+
+SyntheticChildrenFrontEnd *
LibcxxStdListSyntheticFrontEndCreator(CXXSyntheticChildren *,
lldb::ValueObjectSP);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxProxyArray.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxProxyArray.cpp
new file mode 100644
index 0000000..726f065
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxProxyArray.cpp
@@ -0,0 +1,194 @@
+//===-- LibCxxProxyArray.cpp-----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "LibCxx.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/FormattersHelpers.h"
+#include <optional>
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+namespace lldb_private {
+namespace formatters {
+
+/// Data formatter for libc++'s std::"proxy_array".
+///
+/// A proxy_array's are created by using:
+/// std::gslice_array operator[](const std::gslice& gslicearr);
+/// std::mask_array operator[](const std::valarray<bool>& boolarr);
+/// std::indirect_array operator[](const std::valarray<std::size_t>& indarr);
+///
+/// These arrays have the following members:
+/// - __vp_ points to std::valarray::__begin_
+/// - __1d_ an array of offsets of the elements from @a __vp_
+class LibcxxStdProxyArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+ LibcxxStdProxyArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+ ~LibcxxStdProxyArraySyntheticFrontEnd() override;
+
+ llvm::Expected<uint32_t> CalculateNumChildren() override;
+
+ lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;
+
+ lldb::ChildCacheState Update() override;
+
+ bool MightHaveChildren() override;
+
+ size_t GetIndexOfChildWithName(ConstString name) override;
+
+private:
+ /// A non-owning pointer to the array's __vp_.
+ ValueObject *m_base = nullptr;
+ /// The type of the array's template argument T.
+ CompilerType m_element_type;
+ /// The sizeof the array's template argument T.
+ uint32_t m_element_size = 0;
+
+ /// A non-owning pointer to the array's __1d_.__begin_.
+ ValueObject *m_start = nullptr;
+ /// A non-owning pointer to the array's __1d_.__end_.
+ ValueObject *m_finish = nullptr;
+ /// The type of the __1d_ array's template argument T (size_t).
+ CompilerType m_element_type_size_t;
+ /// The sizeof the __1d_ array's template argument T (size_t)
+ uint32_t m_element_size_size_t = 0;
+};
+
+} // namespace formatters
+} // namespace lldb_private
+
+lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::
+ LibcxxStdProxyArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+ : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
+ if (valobj_sp)
+ Update();
+}
+
+lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::
+ ~LibcxxStdProxyArraySyntheticFrontEnd() {
+ // these need to stay around because they are child objects who will follow
+ // their parent's life cycle
+ // delete m_base;
+}
+
+llvm::Expected<uint32_t> lldb_private::formatters::
+ LibcxxStdProxyArraySyntheticFrontEnd::CalculateNumChildren() {
+
+ if (!m_start || !m_finish)
+ return 0;
+ uint64_t start_val = m_start->GetValueAsUnsigned(0);
+ uint64_t finish_val = m_finish->GetValueAsUnsigned(0);
+
+ if (start_val == 0 || finish_val == 0)
+ return 0;
+
+ if (start_val >= finish_val)
+ return 0;
+
+ size_t num_children = (finish_val - start_val);
+ if (num_children % m_element_size_size_t)
+ return 0;
+ return num_children / m_element_size_size_t;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::GetChildAtIndex(
+ uint32_t idx) {
+ if (!m_base)
+ return lldb::ValueObjectSP();
+
+ uint64_t offset = idx * m_element_size_size_t;
+ offset = offset + m_start->GetValueAsUnsigned(0);
+
+ lldb::ValueObjectSP indirect = CreateValueObjectFromAddress(
+ "", offset, m_backend.GetExecutionContextRef(), m_element_type_size_t);
+ if (!indirect)
+ return lldb::ValueObjectSP();
+
+ const size_t value = indirect->GetValueAsUnsigned(0);
+ if (!value)
+ return lldb::ValueObjectSP();
+
+ offset = value * m_element_size;
+ offset = offset + m_base->GetValueAsUnsigned(0);
+
+ StreamString name;
+ name.Printf("[%" PRIu64 "] -> [%zu]", (uint64_t)idx, value);
+ return CreateValueObjectFromAddress(name.GetString(), offset,
+ m_backend.GetExecutionContextRef(),
+ m_element_type);
+}
+
+lldb::ChildCacheState
+lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::Update() {
+ m_base = nullptr;
+ m_start = nullptr;
+ m_finish = nullptr;
+
+ CompilerType type = m_backend.GetCompilerType();
+ if (type.GetNumTemplateArguments() == 0)
+ return ChildCacheState::eRefetch;
+
+ m_element_type = type.GetTypeTemplateArgument(0);
+ if (std::optional<uint64_t> size = m_element_type.GetByteSize(nullptr))
+ m_element_size = *size;
+
+ if (m_element_size == 0)
+ return ChildCacheState::eRefetch;
+
+ ValueObjectSP vector = m_backend.GetChildMemberWithName("__1d_");
+ if (!vector)
+ return ChildCacheState::eRefetch;
+
+ type = vector->GetCompilerType();
+ if (type.GetNumTemplateArguments() == 0)
+ return ChildCacheState::eRefetch;
+
+ m_element_type_size_t = type.GetTypeTemplateArgument(0);
+ if (std::optional<uint64_t> size = m_element_type_size_t.GetByteSize(nullptr))
+ m_element_size_size_t = *size;
+
+ if (m_element_size_size_t == 0)
+ return ChildCacheState::eRefetch;
+
+ ValueObjectSP base = m_backend.GetChildMemberWithName("__vp_");
+ ValueObjectSP start = vector->GetChildMemberWithName("__begin_");
+ ValueObjectSP finish = vector->GetChildMemberWithName("__end_");
+ if (!base || !start || !finish)
+ return ChildCacheState::eRefetch;
+
+ m_base = base.get();
+ m_start = start.get();
+ m_finish = finish.get();
+
+ return ChildCacheState::eRefetch;
+}
+
+bool lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::
+ MightHaveChildren() {
+ return true;
+}
+
+size_t lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEnd::
+ GetIndexOfChildWithName(ConstString name) {
+ if (!m_base)
+ return std::numeric_limits<size_t>::max();
+ return ExtractIndexFromString(name.GetCString());
+}
+
+lldb_private::SyntheticChildrenFrontEnd *
+lldb_private::formatters::LibcxxStdProxyArraySyntheticFrontEndCreator(
+ CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
+ if (!valobj_sp)
+ return nullptr;
+ return new LibcxxStdProxyArraySyntheticFrontEnd(valobj_sp);
+}
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 5d2b4b0..59fc872 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -1089,6 +1089,10 @@ Status NativeProcessLinux::Detach() {
if (GetID() == LLDB_INVALID_PROCESS_ID)
return error;
+ // Cancel out any SIGSTOPs we may have sent while stopping the process.
+ // Otherwise, the process may stop as soon as we detach from it.
+ kill(GetID(), SIGCONT);
+
for (const auto &thread : m_threads) {
Status e = Detach(thread->GetID());
if (e.Fail())
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 44bd02b..be0ddb0 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -459,85 +459,19 @@ TypeSystemClang::ConvertAccessTypeToAccessSpecifier(AccessType access) {
return AS_none;
}
-static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
+static void ParseLangArgs(LangOptions &Opts, ArchSpec arch) {
// FIXME: Cleanup per-file based stuff.
- // Set some properties which depend solely on the input kind; it would be
- // nice to move these to the language standard, and have the driver resolve
- // the input kind + language standard.
- if (IK.getLanguage() == clang::Language::Asm) {
- Opts.AsmPreprocessor = 1;
- } else if (IK.isObjectiveC()) {
- Opts.ObjC = 1;
- }
-
- LangStandard::Kind LangStd = LangStandard::lang_unspecified;
-
- if (LangStd == LangStandard::lang_unspecified) {
- // Based on the base language, pick one.
- switch (IK.getLanguage()) {
- case clang::Language::Unknown:
- case clang::Language::CIR:
- case clang::Language::LLVM_IR:
- case clang::Language::RenderScript:
- llvm_unreachable("Invalid input kind!");
- case clang::Language::OpenCL:
- LangStd = LangStandard::lang_opencl10;
- break;
- case clang::Language::OpenCLCXX:
- LangStd = LangStandard::lang_openclcpp10;
- break;
- case clang::Language::Asm:
- case clang::Language::C:
- case clang::Language::ObjC:
- LangStd = LangStandard::lang_gnu99;
- break;
- case clang::Language::CXX:
- case clang::Language::ObjCXX:
- LangStd = LangStandard::lang_gnucxx98;
- break;
- case clang::Language::CUDA:
- case clang::Language::HIP:
- LangStd = LangStandard::lang_gnucxx17;
- break;
- case clang::Language::HLSL:
- LangStd = LangStandard::lang_hlsl;
- break;
- }
- }
-
- const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
- Opts.LineComment = Std.hasLineComments();
- Opts.C99 = Std.isC99();
- Opts.CPlusPlus = Std.isCPlusPlus();
- Opts.CPlusPlus11 = Std.isCPlusPlus11();
- Opts.CPlusPlus14 = Std.isCPlusPlus14();
- Opts.CPlusPlus17 = Std.isCPlusPlus17();
- Opts.CPlusPlus20 = Std.isCPlusPlus20();
- Opts.Digraphs = Std.hasDigraphs();
- Opts.GNUMode = Std.isGNUMode();
- Opts.GNUInline = !Std.isC99();
- Opts.HexFloats = Std.hasHexFloats();
-
- Opts.WChar = true;
-
- // OpenCL has some additional defaults.
- if (LangStd == LangStandard::lang_opencl10) {
- Opts.OpenCL = 1;
- Opts.AltiVec = 1;
- Opts.CXXOperatorNames = 1;
- Opts.setLaxVectorConversions(LangOptions::LaxVectorConversionKind::All);
- }
-
- // OpenCL and C++ both have bool, true, false keywords.
- Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+ std::vector<std::string> Includes;
+ LangOptions::setLangDefaults(Opts, clang::Language::ObjCXX, arch.GetTriple(),
+ Includes, clang::LangStandard::lang_gnucxx98);
Opts.setValueVisibilityMode(DefaultVisibility);
// Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs is
// specified, or -std is set to a conforming mode.
Opts.Trigraphs = !Opts.GNUMode;
- Opts.CharIsSigned = ArchSpec(triple).CharIsSignedByDefault();
+ Opts.CharIsSigned = arch.CharIsSignedByDefault();
Opts.OptimizeSize = 0;
// FIXME: Eliminate this dependency.
@@ -727,8 +661,7 @@ void TypeSystemClang::CreateASTContext() {
m_ast_owned = true;
m_language_options_up = std::make_unique<LangOptions>();
- ParseLangArgs(*m_language_options_up, clang::Language::ObjCXX,
- GetTargetTriple());
+ ParseLangArgs(*m_language_options_up, ArchSpec(GetTargetTriple()));
m_identifier_table_up =
std::make_unique<IdentifierTable>(*m_language_options_up, nullptr);
diff --git a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 2032c5a..6bfaa54 100644
--- a/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -909,6 +909,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
if (!m_register_map_initialized)
return false;
+ if (m_disasm_context == nullptr)
+ return false;
+
addr_t current_func_text_offset = 0;
int current_sp_bytes_offset_from_fa = 0;
bool is_aligned = false;
@@ -1570,6 +1573,9 @@ bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction(
if (!m_register_map_initialized)
return false;
+ if (m_disasm_context == nullptr)
+ return false;
+
while (offset < size) {
int regno;
int insn_len;
diff --git a/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py b/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
index d8f4516..4d9b036 100644
--- a/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
+++ b/lldb/test/API/commands/frame/diagnose/dereference-function-return/TestDiagnoseDereferenceFunctionReturn.py
@@ -19,6 +19,9 @@ class TestDiagnoseDereferenceFunctionReturn(TestBase):
TestBase.setUp(self)
self.build()
exe = self.getBuildArtifact("a.out")
+ # FIXME: This default changed in lldbtest.py and this test
+ # seems to rely on having it turned off.
+ self.runCmd("settings set target.disable-aslr true")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
self.runCmd("run", RUN_SUCCEEDED)
self.expect("thread list", "Thread should be stopped", substrs=["stopped"])
diff --git a/lldb/test/API/commands/process/detach-resumes/Makefile b/lldb/test/API/commands/process/detach-resumes/Makefile
new file mode 100644
index 0000000..c46619c
--- /dev/null
+++ b/lldb/test/API/commands/process/detach-resumes/Makefile
@@ -0,0 +1,4 @@
+CXX_SOURCES := main.cpp
+ENABLE_THREADS := YES
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/process/detach-resumes/TestDetachResumes.py b/lldb/test/API/commands/process/detach-resumes/TestDetachResumes.py
new file mode 100644
index 0000000..5772729
--- /dev/null
+++ b/lldb/test/API/commands/process/detach-resumes/TestDetachResumes.py
@@ -0,0 +1,59 @@
+"""
+Test that the process continues running after we detach from it.
+"""
+
+import lldb
+import time
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class DetachResumesTestCase(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_detach_resumes(self):
+ self.build()
+ exe = self.getBuildArtifact()
+
+ # The inferior will use this file to let us know it is ready to be
+ # attached.
+ sync_file_path = lldbutil.append_to_process_working_directory(
+ self, "sync_file_%d" % (int(time.time()))
+ )
+
+ # And this one to let us know it is running after we've detached from
+ # it.
+ exit_file_path = lldbutil.append_to_process_working_directory(
+ self, "exit_file_%d" % (int(time.time()))
+ )
+
+ popen = self.spawnSubprocess(
+ self.getBuildArtifact(exe), [sync_file_path, exit_file_path]
+ )
+ lldbutil.wait_for_file_on_target(self, sync_file_path)
+
+ self.runCmd("process attach -p " + str(popen.pid))
+
+ # Set a breakpoint at a place that will be called by multiple threads
+ # simultaneously. On systems (e.g. linux) where the debugger needs to
+ # send signals to suspend threads, these signals will race with threads
+ # hitting the breakpoint (and stopping on their own).
+ bpno = lldbutil.run_break_set_by_symbol(self, "break_here")
+
+ # And let the inferior know it can call the function.
+ self.runCmd("expr -- wait_for_debugger_flag = false")
+
+ self.runCmd("continue")
+
+ self.expect(
+ "thread list",
+ STOPPED_DUE_TO_BREAKPOINT,
+ substrs=["stopped", "stop reason = breakpoint"],
+ )
+
+ # Detach, the process should keep running after this, and not be stopped
+ # by the signals that the debugger may have used to suspend the threads.
+ self.runCmd("detach")
+
+ lldbutil.wait_for_file_on_target(self, exit_file_path)
diff --git a/lldb/test/API/commands/process/detach-resumes/main.cpp b/lldb/test/API/commands/process/detach-resumes/main.cpp
new file mode 100644
index 0000000..e8050fe
--- /dev/null
+++ b/lldb/test/API/commands/process/detach-resumes/main.cpp
@@ -0,0 +1,48 @@
+#include "pseudo_barrier.h"
+#include <chrono>
+#include <fcntl.h>
+#include <fstream>
+#include <stdio.h>
+#include <thread>
+#include <vector>
+
+pseudo_barrier_t barrier;
+
+constexpr size_t nthreads = 5;
+volatile bool wait_for_debugger_flag = true;
+
+void break_here() {}
+
+void tfunc() {
+ pseudo_barrier_wait(barrier);
+
+ break_here();
+}
+
+int main(int argc, char const *argv[]) {
+ lldb_enable_attach();
+
+ if (argc < 3)
+ return 1;
+
+ // Create a file to signal that this process has started up.
+ std::ofstream(argv[1]).close();
+
+ // And wait for it to attach.
+ for (int i = 0; i < 100 && wait_for_debugger_flag; ++i)
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ // Fire up the threads and have them call break_here() simultaneously.
+ pseudo_barrier_init(barrier, nthreads);
+ std::vector<std::thread> threads;
+ for (size_t i = 0; i < nthreads; ++i)
+ threads.emplace_back(tfunc);
+
+ for (std::thread &t : threads)
+ t.join();
+
+ // Create the file to let the debugger know we're running.
+ std::ofstream(argv[2]).close();
+
+ return 0;
+}
diff --git a/lldb/test/API/functionalities/asan/Makefile b/lldb/test/API/functionalities/asan/Makefile
index 4913a18..d66696f 100644
--- a/lldb/test/API/functionalities/asan/Makefile
+++ b/lldb/test/API/functionalities/asan/Makefile
@@ -1,4 +1,8 @@
C_SOURCES := main.c
-CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
+asan: CFLAGS_EXTRAS := -fsanitize=address -g -gcolumn-info
+asan: all
+
+libsanitizers: CFLAGS_EXTRAS := -fsanitize=address -fsanitize-stable-abi -g -gcolumn-info
+libsanitizers: all
include Makefile.rules
diff --git a/lldb/test/API/functionalities/asan/TestMemoryHistory.py b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
index 00162ae..41ab258 100644
--- a/lldb/test/API/functionalities/asan/TestMemoryHistory.py
+++ b/lldb/test/API/functionalities/asan/TestMemoryHistory.py
@@ -8,16 +8,24 @@ from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbplatform
from lldbsuite.test import lldbutil
-
+from lldbsuite.test_event.build_exception import BuildError
class AsanTestCase(TestBase):
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@expectedFailureNetBSD
@skipUnlessAddressSanitizer
def test(self):
- self.build()
+ self.build(make_targets=["asan"])
self.asan_tests()
+ @skipIf(oslist=no_match(["macosx"]))
+ def test_libsanitizers_asan(self):
+ try:
+ self.build(make_targets=["libsanitizers"])
+ except BuildError as e:
+ self.skipTest("failed to build with libsanitizers")
+ self.libsanitizer_tests()
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -26,6 +34,68 @@ class AsanTestCase(TestBase):
self.line_free = line_number("main.c", "// free line")
self.line_breakpoint = line_number("main.c", "// break line")
+ # Test line numbers: rdar://126237493
+ def libsanitizer_tests(self):
+ target = self.createTestTarget()
+
+ self.runCmd(
+ "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
+ )
+
+ self.runCmd("run")
+
+ # In libsanitizers, memory history is not supported until a report has been generated
+ self.expect(
+ "thread list",
+ "Process should be stopped due to ASan report",
+ substrs=["stopped", "stop reason = Use of deallocated memory"],
+ )
+
+ # test the 'memory history' command
+ self.expect(
+ "memory history 'pointer'",
+ substrs=[
+ "Memory deallocated by Thread",
+ "a.out`f2",
+ "main.c",
+ "Memory allocated by Thread",
+ "a.out`f1",
+ "main.c",
+ ],
+ )
+
+ # do the same using SB API
+ process = self.dbg.GetSelectedTarget().process
+ val = (
+ process.GetSelectedThread().GetSelectedFrame().EvaluateExpression("pointer")
+ )
+ addr = val.GetValueAsUnsigned()
+ threads = process.GetHistoryThreads(addr)
+ self.assertEqual(threads.GetSize(), 2)
+
+ history_thread = threads.GetThreadAtIndex(0)
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(
+ history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
+ "main.c",
+ )
+
+ history_thread = threads.GetThreadAtIndex(1)
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(
+ history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
+ "main.c",
+ )
+
+ # let's free the container (SBThreadCollection) and see if the
+ # SBThreads still live
+ threads = None
+ self.assertTrue(history_thread.num_frames >= 2)
+ self.assertEqual(
+ history_thread.frames[1].GetLineEntry().GetFileSpec().GetFilename(),
+ "main.c",
+ )
+
def asan_tests(self):
target = self.createTestTarget()
diff --git a/lldb/test/API/functionalities/asan/TestReportData.py b/lldb/test/API/functionalities/asan/TestReportData.py
index 543c5fe..5e4c179 100644
--- a/lldb/test/API/functionalities/asan/TestReportData.py
+++ b/lldb/test/API/functionalities/asan/TestReportData.py
@@ -8,7 +8,7 @@ import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
-
+from lldbsuite.test_event.build_exception import BuildError
class AsanTestReportDataCase(TestBase):
@skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
@@ -16,9 +16,17 @@ class AsanTestReportDataCase(TestBase):
@skipUnlessAddressSanitizer
@skipIf(archs=["i386"], bugnumber="llvm.org/PR36710")
def test(self):
- self.build()
+ self.build(make_targets=["asan"])
self.asan_tests()
+ @skipIf(oslist=no_match(["macosx"]))
+ def test_libsanitizers_asan(self):
+ try:
+ self.build(make_targets=["libsanitizers"])
+ except BuildError as e:
+ self.skipTest("failed to build with libsanitizers")
+ self.asan_tests(libsanitizers=True)
+
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@@ -29,10 +37,15 @@ class AsanTestReportDataCase(TestBase):
self.line_crash = line_number("main.c", "// BOOM line")
self.col_crash = 16
- def asan_tests(self):
+ def asan_tests(self, libsanitizers=False):
target = self.createTestTarget()
- self.registerSanitizerLibrariesWithTarget(target)
+ if libsanitizers:
+ self.runCmd(
+ "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0"
+ )
+ else:
+ self.registerSanitizerLibrariesWithTarget(target)
self.runCmd("run")
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
index b59b770..613546b 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/TestDataFormatterLibcxxValarray.py
@@ -89,21 +89,93 @@ class LibcxxChronoDataFormatterTestCase(TestBase):
"frame variable sa",
substrs=[
"sa = stride=2 size=4",
- "[0] = 1",
- "[1] = 3",
- "[2] = 5",
- "[3] = 7",
+ "[0] = 11",
+ "[1] = 13",
+ "[2] = 15",
+ "[3] = 17",
"}",
],
)
# check access-by-index
- self.expect("frame variable sa[0]", substrs=["1"])
- self.expect("frame variable sa[1]", substrs=["3"])
- self.expect("frame variable sa[2]", substrs=["5"])
- self.expect("frame variable sa[3]", substrs=["7"])
+ self.expect("frame variable sa[0]", substrs=["11"])
+ self.expect("frame variable sa[1]", substrs=["13"])
+ self.expect("frame variable sa[2]", substrs=["15"])
+ self.expect("frame variable sa[3]", substrs=["17"])
self.expect(
"frame variable sa[4]",
error=True,
substrs=['array index 4 is not valid for "(slice_array<int>) sa"'],
)
+
+ #
+ # std::gslice_array
+ #
+
+ self.expect(
+ "frame variable ga",
+ substrs=[
+ "ga = size=3",
+ "[0] -> [3] = 13",
+ "[1] -> [4] = 14",
+ "[2] -> [5] = 15",
+ "}",
+ ],
+ )
+
+ # check access-by-index
+ self.expect("frame variable ga[0]", substrs=["13"])
+ self.expect("frame variable ga[1]", substrs=["14"])
+ self.expect("frame variable ga[2]", substrs=["15"])
+ self.expect(
+ "frame variable ga[3]",
+ error=True,
+ substrs=['array index 3 is not valid for "(gslice_array<int>) ga"'],
+ )
+ #
+ # std::mask_array
+ #
+
+ self.expect(
+ "frame variable ma",
+ substrs=[
+ "ma = size=2",
+ "[0] -> [1] = 11",
+ "[1] -> [2] = 12",
+ "}",
+ ],
+ )
+
+ # check access-by-index
+ self.expect("frame variable ma[0]", substrs=["11"])
+ self.expect("frame variable ma[1]", substrs=["12"])
+ self.expect(
+ "frame variable ma[2]",
+ error=True,
+ substrs=['array index 2 is not valid for "(mask_array<int>) ma"'],
+ )
+
+ #
+ # std::indirect_array
+ #
+
+ self.expect(
+ "frame variable ia",
+ substrs=[
+ "ia = size=3",
+ "[0] -> [3] = 13",
+ "[1] -> [6] = 16",
+ "[2] -> [9] = 19",
+ "}",
+ ],
+ )
+
+ # check access-by-index
+ self.expect("frame variable ia[0]", substrs=["13"])
+ self.expect("frame variable ia[1]", substrs=["16"])
+ self.expect("frame variable ia[2]", substrs=["19"])
+ self.expect(
+ "frame variable ia[3]",
+ error=True,
+ substrs=['array index 3 is not valid for "(indirect_array<int>) ia"'],
+ )
diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
index 1481d8b..d31951c 100644
--- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
+++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/libcxx/valarray/main.cpp
@@ -13,8 +13,12 @@ int main() {
std::valarray<double> va_double({1.0, 0.5, 0.25, 0.125});
- std::valarray<int> va({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
+ std::valarray<int> va({10, 11, 12, 13, 14, 15, 16, 17, 18, 19});
std::slice_array<int> sa = va[std::slice(1, 4, 2)];
+ std::gslice_array<int> ga = va[std::gslice(
+ 3, std::valarray<std::size_t>(3, 1), std::valarray<std::size_t>(1, 1))];
+ std::mask_array<int> ma = va[std::valarray<bool>{false, true, true}];
+ std::indirect_array<int> ia = va[std::valarray<size_t>{3, 6, 9}];
std::cout << "break here\n";
}
diff --git a/lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py b/lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py
index 1790bd4..2dcbb72 100644
--- a/lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py
+++ b/lldb/test/API/functionalities/fork/concurrent_vfork/TestConcurrentVFork.py
@@ -48,8 +48,6 @@ class TestConcurrentVFork(TestBase):
self.expect("continue", patterns=[r"exited with status = 1[0-4]"])
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_parent_vfork_no_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-parent.
@@ -58,8 +56,6 @@ class TestConcurrentVFork(TestBase):
self.follow_parent_helper(use_fork=False, call_exec=False)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_parent_fork_no_exec(self):
"""
Make sure that debugging concurrent fork() from multiple threads won't crash lldb during follow-parent.
@@ -68,8 +64,6 @@ class TestConcurrentVFork(TestBase):
self.follow_parent_helper(use_fork=True, call_exec=False)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_parent_vfork_call_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-parent.
@@ -78,8 +72,6 @@ class TestConcurrentVFork(TestBase):
self.follow_parent_helper(use_fork=False, call_exec=True)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_parent_fork_call_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-parent.
@@ -88,8 +80,6 @@ class TestConcurrentVFork(TestBase):
self.follow_parent_helper(use_fork=True, call_exec=True)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_child_vfork_no_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-child.
@@ -98,8 +88,6 @@ class TestConcurrentVFork(TestBase):
self.follow_child_helper(use_fork=False, call_exec=False)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_child_fork_no_exec(self):
"""
Make sure that debugging concurrent fork() from multiple threads won't crash lldb during follow-child.
@@ -108,8 +96,6 @@ class TestConcurrentVFork(TestBase):
self.follow_child_helper(use_fork=True, call_exec=False)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_child_vfork_call_exec(self):
"""
Make sure that debugging concurrent vfork() from multiple threads won't crash lldb during follow-child.
@@ -118,8 +104,6 @@ class TestConcurrentVFork(TestBase):
self.follow_child_helper(use_fork=False, call_exec=True)
@skipUnlessPlatform(["linux"])
- # See https://github.com/llvm/llvm-project/issues/85084.
- @skipIf(oslist=["linux"], archs=["aarch64", "arm"])
def test_follow_child_fork_call_exec(self):
"""
Make sure that debugging concurrent fork() from multiple threads won't crash lldb during follow-child.
diff --git a/lldb/test/Shell/lit.cfg.py b/lldb/test/Shell/lit.cfg.py
index 2905695..e24f3fb 100644
--- a/lldb/test/Shell/lit.cfg.py
+++ b/lldb/test/Shell/lit.cfg.py
@@ -50,10 +50,14 @@ llvm_config.with_system_environment(
)
# Enable sanitizer runtime flags.
-config.environment["ASAN_OPTIONS"] = "detect_stack_use_after_return=1"
-config.environment["TSAN_OPTIONS"] = "halt_on_error=1"
-if platform.system() == "Darwin":
- config.environment["MallocNanoZone"] = "0"
+if "Address" in config.llvm_use_sanitizer:
+ config.environment["ASAN_OPTIONS"] = "detect_stack_use_after_return=1"
+ if platform.system() == "Darwin":
+ config.environment["MallocNanoZone"] = "0"
+
+if "Thread" in config.llvm_use_sanitizer:
+ config.environment["TSAN_OPTIONS"] = "halt_on_error=1"
+
# Support running the test suite under the lldb-repro wrapper. This makes it
# possible to capture a test suite run and then rerun all the test from the
diff --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in
index 736dfc3..b69e7bc 100644
--- a/lldb/test/Shell/lit.site.cfg.py.in
+++ b/lldb/test/Shell/lit.site.cfg.py.in
@@ -26,6 +26,7 @@ config.lldb_enable_lua = @LLDB_ENABLE_LUA@
config.lldb_build_directory = "@LLDB_TEST_BUILD_DIRECTORY@"
config.have_lldb_server = @LLDB_TOOL_LLDB_SERVER_BUILD@
config.lldb_system_debugserver = @LLDB_USE_SYSTEM_DEBUGSERVER@
+config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
# The shell tests use their own module caches.
config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-shell")
config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-shell")
diff --git a/lldb/unittests/UnwindAssembly/CMakeLists.txt b/lldb/unittests/UnwindAssembly/CMakeLists.txt
index 136fcd9..d6e4471 100644
--- a/lldb/unittests/UnwindAssembly/CMakeLists.txt
+++ b/lldb/unittests/UnwindAssembly/CMakeLists.txt
@@ -9,3 +9,7 @@ endif()
if ("X86" IN_LIST LLVM_TARGETS_TO_BUILD)
add_subdirectory(x86)
endif()
+
+if (NOT "X86" IN_LIST LLVM_TARGETS_TO_BUILD)
+ add_subdirectory(x86-but-no-x86-target)
+endif()
diff --git a/lldb/unittests/UnwindAssembly/x86-but-no-x86-target/CMakeLists.txt b/lldb/unittests/UnwindAssembly/x86-but-no-x86-target/CMakeLists.txt
new file mode 100644
index 0000000..d28e962
--- /dev/null
+++ b/lldb/unittests/UnwindAssembly/x86-but-no-x86-target/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_lldb_unittest(UnwindAssemblyX86ButNoX86TargetTests
+ Testx86AssemblyInspectionEngine.cpp
+ LINK_LIBS
+ lldbCore
+ lldbSymbol
+ lldbPluginUnwindAssemblyX86
+ LINK_COMPONENTS
+ Support
+ ${LLVM_TARGETS_TO_BUILD}
+ )
diff --git a/lldb/unittests/UnwindAssembly/x86-but-no-x86-target/Testx86AssemblyInspectionEngine.cpp b/lldb/unittests/UnwindAssembly/x86-but-no-x86-target/Testx86AssemblyInspectionEngine.cpp
new file mode 100644
index 0000000..ed093d1
--- /dev/null
+++ b/lldb/unittests/UnwindAssembly/x86-but-no-x86-target/Testx86AssemblyInspectionEngine.cpp
@@ -0,0 +1,103 @@
+//===-- Testx86AssemblyInspectionEngine.cpp -------------------------------===//
+
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h"
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Utility/ArchSpec.h"
+
+#include "llvm/Support/TargetSelect.h"
+
+#include <memory>
+#include <vector>
+
+using namespace lldb;
+using namespace lldb_private;
+
+class Testx86AssemblyInspectionEngine : public testing::Test {
+public:
+ static void SetUpTestCase();
+};
+
+void Testx86AssemblyInspectionEngine::SetUpTestCase() {
+ llvm::InitializeAllTargets();
+ llvm::InitializeAllAsmPrinters();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllDisassemblers();
+}
+
+// only defining the register names / numbers that the unwinder is actually
+// using today
+
+// names should match the constants below. These will be the eRegisterKindLLDB
+// register numbers.
+
+const char *x86_64_reg_names[] = {"rax", "rbx", "rcx", "rdx", "rsp", "rbp",
+ "rsi", "rdi", "r8", "r9", "r10", "r11",
+ "r12", "r13", "r14", "r15", "rip"};
+
+enum x86_64_regs {
+ k_rax = 0,
+ k_rbx = 1,
+ k_rcx = 2,
+ k_rdx = 3,
+ k_rsp = 4,
+ k_rbp = 5,
+ k_rsi = 6,
+ k_rdi = 7,
+ k_r8 = 8,
+ k_r9 = 9,
+ k_r10 = 10,
+ k_r11 = 11,
+ k_r12 = 12,
+ k_r13 = 13,
+ k_r14 = 14,
+ k_r15 = 15,
+ k_rip = 16
+};
+
+std::unique_ptr<x86AssemblyInspectionEngine> Getx86_64Inspector() {
+
+ ArchSpec arch("x86_64-apple-macosx");
+ std::unique_ptr<x86AssemblyInspectionEngine> engine(
+ new x86AssemblyInspectionEngine(arch));
+
+ std::vector<x86AssemblyInspectionEngine::lldb_reg_info> lldb_regnums;
+ int i = 0;
+ for (const auto &name : x86_64_reg_names) {
+ x86AssemblyInspectionEngine::lldb_reg_info ri;
+ ri.name = name;
+ ri.lldb_regnum = i++;
+ lldb_regnums.push_back(ri);
+ }
+
+ engine->Initialize(lldb_regnums);
+ return engine;
+}
+
+TEST_F(Testx86AssemblyInspectionEngine, TestSimple64bitFrameFunction) {
+ std::unique_ptr<x86AssemblyInspectionEngine> engine = Getx86_64Inspector();
+
+ // 'int main() { }' compiled for x86_64-apple-macosx with clang
+ uint8_t data[] = {
+ 0x55, // offset 0 -- pushq %rbp
+ 0x48, 0x89, 0xe5, // offset 1 -- movq %rsp, %rbp
+ 0x31, 0xc0, // offset 4 -- xorl %eax, %eax
+ 0x5d, // offset 6 -- popq %rbp
+ 0xc3 // offset 7 -- retq
+ };
+
+ AddressRange sample_range(0x1000, sizeof(data));
+
+ UnwindPlan unwind_plan(eRegisterKindLLDB);
+ EXPECT_FALSE(engine->GetNonCallSiteUnwindPlanFromAssembly(
+ data, sizeof(data), sample_range, unwind_plan));
+}
diff --git a/lldb/unittests/tools/CMakeLists.txt b/lldb/unittests/tools/CMakeLists.txt
index 055fc6e..42b0c25 100644
--- a/lldb/unittests/tools/CMakeLists.txt
+++ b/lldb/unittests/tools/CMakeLists.txt
@@ -1,3 +1,5 @@
if(LLDB_TOOL_LLDB_SERVER_BUILD)
- add_subdirectory(lldb-server)
+ if (NOT LLVM_USE_SANITIZER MATCHES ".*Address.*")
+ add_subdirectory(lldb-server)
+ endif()
endif()