llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Charles Zablit (charles-zablit)
<details>
<summary>Changes</summary>
IRForTarget didn't correctly handle the Microsoft C++ ABI when preparing JIT'd
expressions:
- `CreateResultVariable` could match a compiler generated dynamic initializer
function instead of the result variable, since both share the same mangled
substring under the MS ABI.
- `RemoveCXAAtExit` only stripped `__cxa_atexit` calls (Itanium ABI). On the MS
ABI, static destructors are registered via plain `atexit`.
Example:
```cpp
struct Foo {
Foo() : x(42) {}
~Foo() {}
int x;
};
void bar() {
static Foo f;
// <breakpoint here>
}
```
Evaluating `f.x` at the breakpoint on Windows previously could resolve against
the wrong symbol or crash, because the MS-ABI-specific dynamic initializer
function and atexit-registered destructor thunk weren't accounted for.
Changes
- Restrict result variable lookup to GlobalVariables, so the dynamic
initializer function is skipped.
- Strip `atexit` registrations in addition to `__cxa_atexit`.
- Clear the body of any atexit destructor thunk.
This is needed for:
- https://github.com/swiftlang/llvm-project/pull/13517
---
Full diff: https://github.com/llvm/llvm-project/pull/212521.diff
1 Files Affected:
- (modified) lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp (+30-3)
``````````diff
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index adfb5bd1eca94..114e44b34888c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -180,6 +180,11 @@ bool IRForTarget::CreateResultVariable(llvm::Function
&llvm_function) {
// on Windows, so let's only check for Itanium guard variables.
bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false);
+ // Skip non-globals, e.g. the MS ABI dynamic initializer function that
+ // shares a mangled name with the result variable.
+ if (!isa<GlobalVariable>(value_symbol.second))
+ continue;
+
if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) {
found_result = true;
m_result_is_pointer = true;
@@ -1181,6 +1186,7 @@ bool IRForTarget::HandleObjCClass(Value
*classlist_reference) {
bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
std::vector<CallInst *> calls_to_remove;
+ llvm::SmallVector<llvm::Function *, 2> dead_atexit_callbacks;
for (Instruction &inst : basic_block) {
CallInst *call = dyn_cast<CallInst>(&inst);
@@ -1193,21 +1199,42 @@ bool IRForTarget::RemoveCXAAtExit(BasicBlock
&basic_block) {
llvm::Function *func = call->getCalledFunction();
- if (func && func->getName() == "__cxa_atexit")
+ // Itanium ABI uses __cxa_atexit; MS ABI uses plain atexit.
+ if (func &&
+ (func->getName() == "__cxa_atexit" || func->getName() == "atexit"))
remove = true;
llvm::Value *val = call->getCalledOperand();
- if (val && val->getName() == "__cxa_atexit")
+ if (val && (val->getName() == "__cxa_atexit" || val->getName() ==
"atexit"))
remove = true;
- if (remove)
+ if (remove) {
+ // MS ABI callback thunks (mangled "??__F...") reference the static
+ // they destroy; track them to clear once the call is gone.
+ if (call->arg_size() > 0)
+ if (auto *cb = dyn_cast<llvm::Function>(
+ call->getArgOperand(0)->stripPointerCasts()))
+ if (cb->hasInternalLinkage() && cb->getName().starts_with("??__"))
+ dead_atexit_callbacks.push_back(cb);
calls_to_remove.push_back(call);
+ }
}
for (CallInst *ci : calls_to_remove)
ci->eraseFromParent();
+ // Clear the body of any orphaned atexit-destructor thunk so it no longer
+ // references the statics it used to destroy.
+ for (llvm::Function *cb : dead_atexit_callbacks) {
+ if (!cb->use_empty())
+ continue;
+ cb->deleteBody();
+ llvm::BasicBlock *entry =
+ llvm::BasicBlock::Create(cb->getContext(), "", cb);
+ llvm::ReturnInst::Create(cb->getContext(), entry);
+ }
+
return true;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/212521
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits