<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/62357>62357</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
AddressSanitizer: heap-use-after-free if using static MCJIT
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
frasercrmck
</td>
</tr>
</table>
<pre>
I've found that it's possible for a static `MCJIT` to access freed memory during its destructor, if the static singleton `GDBJITRegistrationListener` it relies on is freed first.
```
WARNING: ThreadSanitizer: heap-use-after-free (pid=532379)
Read of size 8 at 0x7b7400000000 by main thread (mutexes: write M0, write M1):
#0 isEqual /llvm/include/llvm/ADT/DenseMapInfo.h:143:19 (lli+0x1c8227c)
#1 LookupBucketFor<unsigned long> /llvm/include/llvm/ADT/DenseMap.h:633:11 (lli+0x1c8227c)
#2 LookupBucketFor<unsigned long> /llvm/include/llvm/ADT/DenseMap.h:664:9 (lli+0x1c8227c)
#3 find /llvm/include/llvm/ADT/DenseMap.h:154:9 (lli+0x1c8227c)
#4 (anonymous namespace)::GDBJITRegistrationListener::notifyFreeingObject(unsigned long) /llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp:201:59 (lli+0x1c8227c)
#5 notifyFreeingObject /llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:676:8 (lli+0x1d3760e)
#6 llvm::MCJIT::~MCJIT() /llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:103:7 (lli+0x1d3760e)
#7 llvm::MCJIT::~MCJIT() /llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:94:17 (lli+0x1d37ec9)
#8 operator() /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/unique_ptr.h:95:2 (lli+0x11a9a33)
#9 ~unique_ptr /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../include/c++/12.2.0/bits/unique_ptr.h:396:4 (lli+0x11a9a33)
#10 Foo::~Foo() /llvm/tools/lli/lli.cpp:480:7 (lli+0x11a9a33)
#11 cxa_at_exit_callback_installed_at(void*) crtstuff.c (lli+0x111e570)
#12 __cxx_global_var_init.136 /llvm/tools/lli/lli.cpp (lli+0x11c8f01)
#13 _GLOBAL__sub_I_lli.cpp /llvm/tools/lli/lli.cpp (lli+0x11c8f01)
#14 <null> <null> (libc.so.6+0x232cf) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)
Previous write of size 8 at 0x7b7400000000 by main thread:
#0 operator delete(void*) <null> (lli+0x11a2a8c)
#1 llvm::deallocate_buffer(void*, unsigned long, unsigned long) /llvm/lib/Support/MemAlloc.cpp:25:3 (lli+0x24dbe59)
#2 ~DenseMap /llvm/include/llvm/ADT/DenseMap.h:757:5 (lli+0x1c8158f)
#3 (anonymous namespace)::GDBJITRegistrationListener::~GDBJITRegistrationListener() /llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp:166:1 (lli+0x1c8158f)
#4 cxa_at_exit_callback_installed_at(void*) crtstuff.c (lli+0x111e570)
#5 instance /llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp:116:5 (lli+0x1c80d6f)
#6 llvm::JITEventListener::createGDBRegistrationListener() /llvm/lib/ExecutionEngine/GDBRegistrationListener.cpp:247:11 (lli+0x1c80d6f)
#7 <null> <null> (libc.so.6+0x232cf) (BuildId: 9c28cfc869012ebbd43cdb0f1eebcd14e1b8bdd8)
```
I haven't checked with any of the other JITs.
This was checked in LLVM 15 and on a recent version of LLVM 16. I believe it may stem from c4ccf608c2380796d64db108eed3b24c1b0140ef but I'm not 100% on that.
This was quite easily reproduceable by patching `lli` to have a static class holding an `ExecutionEngine`, and setting the `ExecutionEngine` to that. It must hold a finalized object (to trigger the notify behaviour).
``` patch
diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp
index ff73ac18f5ee..e877ddea03d4 100644
--- a/llvm/tools/lli/lli.cpp
+++ b/llvm/tools/lli/lli.cpp
@@ -424,6 +424,13 @@ int runOrcJIT(const char *ProgName);
void disallowOrcOptions();
Expected<std::unique_ptr<orc::ExecutorProcessControl>> launchRemote();
+class Foo {
+public:
+ std::unique_ptr<ExecutionEngine> JIT;
+};
+
+static Foo F;
+
//===----------------------------------------------------------------------===//
// main Driver function
//
@@ -522,6 +529,10 @@ int main(int argc, char **argv, char * const *envp) {
builder.setTargetOptions(Options);
+ F.JIT.reset(builder.create());
+ F.JIT->finalizeObject();
+ exit(1);
+
std::unique_ptr<ExecutionEngine> EE(builder.create());
if (!EE) {
if (!ErrorMsg.empty())
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzMWEtvGzkS_jX0pSCBTfZLBx8k2woUOJNBxtg9CmyyWuKmRWpItiLnkN--YLdkPSfRIJPFGkKbYpPfV8Uq1kPCe70wiPckm5Ds8U60YWndfe2ERyfdSn6-q6x6vZ8RVmwQatsaBWEpAuhAWOFhbb3XVRNfORDggwhaAsnph4f3sxeSUwgWhJToPdQOUcEKV9a9gmqdNgvQwYNCH1wrg3WEPYCuISxxj-S1WTQYrImY7x4n72cvn3ChfXAiaGuetQ9o0EUiHcBho9GDNaD3dLV2PgwJfSR0vHvmdPfpvv57_Om32W_vCB_Dy9KhUH8Io4P-ii5OLVGsB63HgagDukHEBMLKtVaEP2ac8WJE2KhHAviEQoGtweuvCCWIAHRbVEVKd39QvcJKaAOhY4pIqzbgFn3k-uJ0QPhA4ynsxkkE5-M9PgBhnIL2T3-2ogHCpk2zWRE21UY2rcLDxPjxhbDpIxqPH8R6Zmo7XBI-TlIen6PI3DSasAndJrJkrJBHanQ0CTxb-7ldT1r5GcPUOsIfWtO5i4LGmgXhT7dL0LHnvGNPbmBnv4A9Twkf36I6h1ob9Tfhk-xW-DSuEcaa15VtPRixQr8WEne25uPv-Hn33tig69epQ9Rm8bH6D8pAWHl6PGx0JH-jK8KmT1uUbUR7MgttojbvHifXWIZyvSZ8zGhC-Di7RaUMrsh0gwB9lNj939HmRU74uDxhVbzIKZ6z5tDBd2fSI3XDbzvU8rZDuCZDQqOnFjfIUPwyGUbRn5ILGVCOzmUowa7RiS6A7glb7wibVtoQNh0Oe-o8JWy6kJKw6bbM53k6WMtBo027HSxMS9g0YUM2pPsdZ4_DJZCETbrPYUOlg4-sRv_Z4nwdXHcnRll0oxMNEjESnJ9rMIJvh63_N-LzUfTE9Ab5EwpTa3emj6NzwwdrG9991f1zZ-S0pBeO9hcUCcitmIswx60OcymaphLy81wbH0TToJqLGAU2VivCxpFduuBDW9dDeQqfYFbQC3gG87ncbueLxlaimW-Em2ujwzDh-Y_0OIWXZU2TC3gO83fPHyfj5_nct9V8Nj_s_WnsFAh_MG3TdEnhaMjKRldy6O0w7wAYZ7LuDVNOWt2omYqJdyRZKWtZ5iOaMKwqlXKpKloniJVUSYpJVVZKlW_Ee_rfHW50jOF9ur4981_m9P0NBoUNBjy15JlOB0dhorySuA8RSaFoGitFwHnV1jW6Y9wHOEsZFxOXoeuPdr22LsRQhatxxN4ni3jV-bF4LFUVZhfBisG3fd78mxm2yIqYj87SUZKV9WUC_8kM--07C26N6d9PrkkeY8t5KXRNmfSX3vsMOiAj8edVSvIr9qEqv1DpOHG_n708bdCEUwNIhyLgX_D9QyZgaXGtHL0mcPE_jzCnTUr_nMFSbNAQVgSQS5SfUcEXHZYgzGsMPrFvsmGJDt7PXvxJ0_Oy1B6-CP-2Txt4fv7XB0gyEEbFlkmAQ4kmwAad19ZExH5JPoQZVLG32mBss1biFXzAFdTOrkCmUtY5LSXjJS1GucpTVSW0RFS8YqlMKpqkFGuo2gCxkVzFYhESSgnLInHsJ68L-2cbwyoKr5tXcLh2VrUSRew3q1dYiyCXsYkkOY3265vNeESHTlQ2wntY2kbFhaJrI8_9JO86rngKHkOI6-JBXl0YCTpxYRZg1frQQYOIDYNo9FdUYPe1bxnXOr1YoOsA-woZKlyKmDQcYaPrfWmvWD-pdF3DYLDQAcSPMmX1o3KjQ9RG4RbquuBCJmWdIQ6HWBaFUigoV2k0TJ6m_eLBYPBD3p30u5pqcqMYJKUkpTBIWUrYQywxJv0w4bB7p00A15qPTvaltLTGR8cXsUIc_-7s4jex6mP6ZHdbYxQEpX3Mel8-OvlxHc3n-4BxWPa0XaMMqAh_8EH1EedQ-xH-YJ3sZ3sXsO53ZyV6_2BNcDZe_Xj7G9EaufyEK9sl7GOKt0PpHXBqLZBi8ja7bqtGy7cqIB7bdUHOXZA_QddjHKBI8XjydT_YXYDIPL1cEINn_PDH_jP4R_7e4Hbox1R9-fPo9AYd1K2RUatTYU4cI2Ns7xgZG0XHoMeOEdEIK-NQuIWMN3jvGYSNhVtsjqeg9x3Cxmg26y4-FyeWgioGa3RDj-FFuAWGg-u8ja6YF6bD2LE59Biz8B6lT187nzjexybQbxkQ_rQPGm8t_PnSmPEJK5Oz-bfUdLPPPD3dIBwA6Bq6-SRuODqkmAaPXjpn3Qe_GOJqHV4PQNeC2Z2652rER-IO75O8ZCnP6IjeLe_TgtNixKokR0qzlFWVSMtCFWUuM0pVcafvGWWcpixLMppmdJjUtawFVyKvJUupICnFldDNMEaboXWLO-19i_c541lx14gKG7__YdPdx0WDql14ktJG--AP24IODd6PlXLo_Q9__tM1tD5mid0N63r2u9Y198sQ1j4apHPnhQ7LthpKuzoqVKIQa2d7e087eWOA7ET-bwAAAP__TzxS-w">