<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/56171>56171</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
JIT-ed code crashed when throwing c++ exception on windows x64 debug build
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mengzhisy
</td>
</tr>
</table>
<pre>
win64 Debug Build (Release Build is ok)
Consider the following code, Process crashed when run to `throw 42;`
If we use LLVMAddGlobalMapping instead of Engine::addGlobalMapping, the test passes, which is weird.
```
#include "MCJITTestAPICommon.h"
#include "llvm-c/Analysis.h"
#include "llvm-c/Core.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Target.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm-c/Transforms/Scalar.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Host.h"
#include "gtest/gtest.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
using namespace llvm;
namespace {
class MCJITCAPITest : public testing::Test {
protected:
MCJITCAPITest() {
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
}
void SetUp() override {
Module = nullptr;
Function = nullptr;
Engine = nullptr;
Error = nullptr;
}
void TearDown() override {
if (Engine)
LLVMDisposeExecutionEngine(Engine);
else if (Module)
LLVMDisposeModule(Module);
}
void buildMCJITOptions() {
LLVMInitializeMCJITCompilerOptions(&Options, sizeof(Options));
Options.OptLevel = 2;
// Just ensure that this field still exists.
Options.NoFramePointerElim = false;
}
void buildMCJITEngine() {
ASSERT_EQ(
0, LLVMCreateMCJITCompilerForModule(&Engine, Module, &Options,
sizeof(Options), &Error));
}
LLVMModuleRef Module;
LLVMValueRef Function;
LLVMValueRef Function2;
LLVMMCJITCompilerOptions Options;
LLVMExecutionEngineRef Engine;
char* Error;
};
} // end anonymous namespace
static int localTestFunc() {
throw 42;
}
TEST_F(MCJITCAPITest, addGlobalMapping) {
Module = LLVMModuleCreateWithName("testModule");
LLVMTypeRef FunctionType = LLVMFunctionType(LLVMInt32Type(), nullptr, 0, 0);
LLVMValueRef MappedFn = LLVMAddFunction(Module, "mapped_fn", FunctionType);
Function = LLVMAddFunction(Module, "test_fn", FunctionType);
LLVMBasicBlockRef Entry = LLVMAppendBasicBlock(Function, "");
LLVMBuilderRef Builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(Builder, Entry);
LLVMValueRef RetVal =
LLVMBuildCall2(Builder, FunctionType, MappedFn, nullptr, 0, "");
LLVMBuildRet(Builder, RetVal);
LLVMDisposeBuilder(Builder);
LLVMVerifyModule(Module, LLVMAbortProcessAction, &Error);
LLVMDisposeMessage(Error);
buildMCJITOptions();
buildMCJITEngine();
// If we use LLVMAddGlobalMapping instead of Engine::addGlobalMapping, the test passes, which is weird.
// LLVMAddGlobalMapping(
// Engine, MappedFn,
// reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(&localTestFunc)));
unwrap(Engine)->addGlobalMapping(
unwrap<GlobalValue>(MappedFn), reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(&localTestFunc)));
uint64_t raw = LLVMGetFunctionAddress(Engine, "test_fn");
int (*usable)() = (int (*)())raw;
int catched = 0;
try {
usable();
} catch (int x) {
catched = x;
}
EXPECT_EQ(catched, 42);
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzFWFtz4jYU_jXmRbMMMbfwwAMxsM3OsqUJ3fYtI-wDqCskjySHsL--R_Idm5B9aT0esKVP536RvJXReXpiYjQgc9gme_KQMB4Rz79_Ag5UQzbANJE_PH_i9eZebxZIoVkEipgDkJ3kXCKJPQllBJ4fkLWSIWhNQkX1ASJyOoAgKhHESOKNeuag5IkMfK__gG8pxccdOQFJkN_Xr99Xsyj6zOWW8hWNY0uZCW2ARkTuyELsmQCvP8ObXuAscyuSAW1ITLUGbYdOBxYerAonYCrqphwt6_ROX_0-EyFPIkDl_VXw5XGzQSqz9WMgj0cpugccboNy_nr8FHr-ciYoP2umbyMDqeA2avEGYWKYFKnGtxdsqNqD-QBOUaF3Uh3ROMs1WmlFBd2Dcp4G9YsEnkPK6fuLmsrYdRDa9xUcpTpnEtyi8pzEsVQGn1ywfhz-m9TXDbO34YIg919F_Yo673jL_SbaxrGgR9AxDYE4QpgAFUg56Y2ziZCje4iLxgBD0UYkwbgncbLlLHRxbsPeJUM6ma-MlTRoYYjspBsheNUoYZJjRpdLSHY9CmYY5ewnfKOGvUIaVym6EPl98Ewf14oJA6plmTeeV9W2Q6-SReQZzJ9xJpR8BaVYBE3pVjJKOI7350QknMdGNWRaJsLF1rug1E_vQ5SS6irimhoboGouT-KmJmxn62weQZP6pL1sKZwzHUsNjYCrrLsUGziW0ZR4aqxbxHNUBf4RRbe2XriI-j22oulrAWVZlXGSxqA8xoyDqq4cFS8B0QiUOxwuxiZtqmazXfz_Cq_AnbP8i7zKwZileJMvCeYJCJ0obBQHavAHW8OOAbY5TCfOCbwxbXS3ndU3uVSYqGvpwnvB2dEx3VG0-i-arfBlq9Vmz8-Lp83L4g8LaLivZ61kDRsooKZu1KVUhUvRrDmbgOSjAalZu0n9I1erixxllzctHmuxiNUgleoJdrl81TUW8J3yxM3niX0b4TcgbWGXO7UBvkg3Sznfd1SQ4YGimrO0TpRBh1pWnou4AxERKqQ4H2Wiy05QtYg2WEND3O0YwiX2VVulrUZtIVLdRRV8K7Q2i-fNy9Imdb3mB6S5a7ogXSmxpX_SOPuLmcM3FN1J5Nv-k8eUf-ltu3Rzjmtuse8F3eog0kurhOn72XsWT3npxcde9tPkU_jfqgTRUhRMcCtZRE1Z4GyY-keHfdkJJ3xA6vJMWqpIrbHcoG5tc5t2rsAD1Sx8QKf_SGPNqHPJBMUUUYlATiVTx-uK9bMNnaWYPRY0U29moy092mLWUjPLJEPNzEJECC0WBamc7_rjCQw-W7bNluAIBZRzv061bqug8GlbNNxQ_sntWyq0U3na8FkvLE1SPLVFglMSFNudG80zLcuzLe48s4PQrOKrsjheEWCFC3AvbDv8JbLEX2m9NZrtfeaCWFab8PofTmAF7zaORdcrYfaqNLMyLNqAClyDjhWYl5Bi5esHtv1ivfb6CyTeMp_gCAbXi0kR6KyLKjxpaWqJOCkaVzdkn3B50y4XPTxb1g9SmEuYlG2pl6t__4UeFW1w6WjwYoiip6JYfAaT5yR6SWGAVtRtFLu6eWwvczLgCYhu081l1s2QOj6WgGIKb2TfIp3FhtSE9qOCXd6rsXI183IXlXNtO4WktHIh3lp3YVV2b-27GReWf68XQbZZy5ZY0wxq9rjo0MUXiE407UeT_oR2DDMcppiyn5Cl_ZxS_4bier770uL5D3jjTjUEVwAI3jgTyZMmb6MBidzHHFcCOoni04MxsbYp63Jkj1082XZDac-y2ZHWne7x1PgPnhrxlWmd2NxdDkd347vOYXp_F4120danuxAm0XAYAfW34-Fk1xtFg3sfOpxu8eQx9YYP3nDeYVO_5_u9kd_vjYZ3vUl3DMP7aHzvj-l9r0dHY2_QgyNlvGsZd6Xad9TUyYCCa5zkbg9eTGIpYXsBkNOniTlINT2C2P_E_fu54wSeOmn_BRhphfg">