johannes created this revision. johannes added reviewers: spyffe, clayborg, jasonmolenda. Herald added a subscriber: aprantl. Herald added a project: LLDB. johannes updated this revision to Diff 233856. johannes edited the summary of this revision. johannes added a comment.
typo Fixes PR41237 - SIGSEGV on call expression evaluation when debugging clang The address computation in lldb fails only on executables linked with lld as opposed to ld, and only with very specific inputs. I haven't found out why it does not trigger more often. In the object file produced by the added test, the function four() is defined in two different DW_TAG_subprogram entries of DWARF debug info: once with a DW_AT_object_pointer, and once without. For computing function addresses, lldb would previously use the whatever is the first of those entries. Presumably because of the missing DW_AT_object_pointer entry, the function has no associated symbol, so lldb failed to compute the function address. This patch modifies the address lookup to prefer function entries with symbols to fix that. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D71487 Files: lldb/source/Expression/IRExecutionUnit.cpp lldb/test/Shell/Expr/Inputs/function-address-lib.cpp lldb/test/Shell/Expr/Inputs/function-address-main.cpp lldb/test/Shell/Expr/Inputs/function-address-shared.h lldb/test/Shell/Expr/TestFunctionAddress.lldb Index: lldb/test/Shell/Expr/TestFunctionAddress.lldb =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/TestFunctionAddress.lldb @@ -0,0 +1,9 @@ +# RUN: %clangxx_host %p/Inputs/function-address-main.cpp %p/Inputs/function-address-lib.cpp -g -fuse-ld=lld -o %t +# RUN: %lldb %t -s %s 2>&1 | FileCheck %s +b main +run +next +expr argv.four() +# CHECK: expr argv.four() +# CHECK-NEXT: (int) $0 = 4 +# CHECK-NOT: SIGSEGV Index: lldb/test/Shell/Expr/Inputs/function-address-shared.h =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/Inputs/function-address-shared.h @@ -0,0 +1,23 @@ +#ifndef function_address_shared_h +#define function_address_shared_h +namespace llvm_namespace { +struct TinyVectorBase { + int SomeInlineInitializedMember = 0; +}; +struct TinyVector : TinyVectorBase { + TinyVector *Self; + + TinyVector() : Self(getFirstEl()) {} + TinyVector(bool) : TinyVector() { nop(four()); } + int four() const { return 4; } + TinyVector *getFirstEl() { return this; } + char *begin() { return nullptr; } + char *end() { return begin() + four(); } + void clear() { nop(begin()), nop(end()); } + + void nop(void *) {} + void nop(int) {} +}; +} // end namespace llvm_namespace +using llvm_namespace::TinyVector; +#endif // function_address_shared_h Index: lldb/test/Shell/Expr/Inputs/function-address-main.cpp =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/Inputs/function-address-main.cpp @@ -0,0 +1,4 @@ +#include "function-address-shared.h" +int main() { + TinyVector argv(true); +} Index: lldb/test/Shell/Expr/Inputs/function-address-lib.cpp =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/Inputs/function-address-lib.cpp @@ -0,0 +1,4 @@ +#include "function-address-shared.h" +void (*ErrorHandler)(); +void LLVMErrorHandler() { TinyVector().clear(); } +void SetErrorHandler() { ErrorHandler = LLVMErrorHandler; } Index: lldb/source/Expression/IRExecutionUnit.cpp =================================================================== --- lldb/source/Expression/IRExecutionUnit.cpp +++ lldb/source/Expression/IRExecutionUnit.cpp @@ -830,6 +830,9 @@ if (load_address != LLDB_INVALID_ADDRESS) { if (is_external) { + // Keep looking for a function entry with a symbol. + if (candidate_sc.function && !candidate_sc.symbol) + continue; return true; } else if (best_internal_load_address == LLDB_INVALID_ADDRESS) { best_internal_load_address = load_address; @@ -844,8 +847,8 @@ load_address = 0; return true; } - - return false; + + return load_address != LLDB_INVALID_ADDRESS; }; if (sc.module_sp) {
Index: lldb/test/Shell/Expr/TestFunctionAddress.lldb =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/TestFunctionAddress.lldb @@ -0,0 +1,9 @@ +# RUN: %clangxx_host %p/Inputs/function-address-main.cpp %p/Inputs/function-address-lib.cpp -g -fuse-ld=lld -o %t +# RUN: %lldb %t -s %s 2>&1 | FileCheck %s +b main +run +next +expr argv.four() +# CHECK: expr argv.four() +# CHECK-NEXT: (int) $0 = 4 +# CHECK-NOT: SIGSEGV Index: lldb/test/Shell/Expr/Inputs/function-address-shared.h =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/Inputs/function-address-shared.h @@ -0,0 +1,23 @@ +#ifndef function_address_shared_h +#define function_address_shared_h +namespace llvm_namespace { +struct TinyVectorBase { + int SomeInlineInitializedMember = 0; +}; +struct TinyVector : TinyVectorBase { + TinyVector *Self; + + TinyVector() : Self(getFirstEl()) {} + TinyVector(bool) : TinyVector() { nop(four()); } + int four() const { return 4; } + TinyVector *getFirstEl() { return this; } + char *begin() { return nullptr; } + char *end() { return begin() + four(); } + void clear() { nop(begin()), nop(end()); } + + void nop(void *) {} + void nop(int) {} +}; +} // end namespace llvm_namespace +using llvm_namespace::TinyVector; +#endif // function_address_shared_h Index: lldb/test/Shell/Expr/Inputs/function-address-main.cpp =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/Inputs/function-address-main.cpp @@ -0,0 +1,4 @@ +#include "function-address-shared.h" +int main() { + TinyVector argv(true); +} Index: lldb/test/Shell/Expr/Inputs/function-address-lib.cpp =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/Inputs/function-address-lib.cpp @@ -0,0 +1,4 @@ +#include "function-address-shared.h" +void (*ErrorHandler)(); +void LLVMErrorHandler() { TinyVector().clear(); } +void SetErrorHandler() { ErrorHandler = LLVMErrorHandler; } Index: lldb/source/Expression/IRExecutionUnit.cpp =================================================================== --- lldb/source/Expression/IRExecutionUnit.cpp +++ lldb/source/Expression/IRExecutionUnit.cpp @@ -830,6 +830,9 @@ if (load_address != LLDB_INVALID_ADDRESS) { if (is_external) { + // Keep looking for a function entry with a symbol. + if (candidate_sc.function && !candidate_sc.symbol) + continue; return true; } else if (best_internal_load_address == LLDB_INVALID_ADDRESS) { best_internal_load_address = load_address; @@ -844,8 +847,8 @@ load_address = 0; return true; } - - return false; + + return load_address != LLDB_INVALID_ADDRESS; }; if (sc.module_sp) {
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits