[llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Greetings, LLVM wizards.

I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:

exec_engine->runStaticConstructorsDestructors(false);
exec_engine->runFunctionAsMain(function, argvec, NULL);

execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().

This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.

Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.

Thanks,
Geoff

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Hi Geoff,

I hit the same problem some time ago.
The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
That's basically the reason of the crash.

From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
That function would record atexit handlers, which you can call manually after running your program.
Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.

I think this is the right place to ask such questions.
Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.

I hope it helps.

Cheers,
Alex.

> On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
>
> Greetings, LLVM wizards.
>
> I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
>
> exec_engine->runStaticConstructorsDestructors(false);
> exec_engine->runFunctionAsMain(function, argvec, NULL);
>
> execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
>
> This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
>
> Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
>
> Thanks,
> Geoff
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
--
AlexDenisov
Software Engineer, https://lowlevelbits.org

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

signature.asc (499 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Wow, now that is an answer. Thank you very much!

On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
Hi Geoff,

I hit the same problem some time ago.
The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
That's basically the reason of the crash.

From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
That function would record atexit handlers, which you can call manually after running your program.
Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.

I think this is the right place to ask such questions.
Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.

I hope it helps.

Cheers,
Alex.

> On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
>
> Greetings, LLVM wizards.
>
> I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
>
> exec_engine->runStaticConstructorsDestructors(false);
> exec_engine->runFunctionAsMain(function, argvec, NULL);
>
> execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
>
> This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
>
> Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
>
> Thanks,
> Geoff

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
In reply to this post by Muhui Jiang via llvm-dev
On Alex's advice I am switching from MCJIT to the Orc API to compile and execute functions. Starting from the new clang-interpreter example in the source code (top of the tree!), I am able to execute my functions all right... as long as there are no constructors and destructors to call.

My question: is there a simple way, with the Orc API, to run a module's constructors and destructors? I see how OrcMCJITReplacement does it, calling getConstructors() and getDestructors() when a module is added, and running them later using a layer, but is there maybe a simpler way that I am missing? I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...

Thanks,
Geoff

On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
Hi Geoff,

I hit the same problem some time ago.
The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
That's basically the reason of the crash.

From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
That function would record atexit handlers, which you can call manually after running your program.
Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.

I think this is the right place to ask such questions.
Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.

I hope it helps.

Cheers,
Alex.

> On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
>
> Greetings, LLVM wizards.
>
> I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
>
> exec_engine->runStaticConstructorsDestructors(false);
> exec_engine->runFunctionAsMain(function, argvec, NULL);
>
> execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
>
> This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
>
> Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
>
> Thanks,
> Geoff

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Hi Geoff,

As far as I know there is no "simple" way to do that.

> I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...

What do you mean by "invent secret names"? If you don't need to JIT native object files, but only bitcode, then MCJIT' approach should work. Just use that "snippet" in your code :)

> On 19. Jun 2018, at 17:54, Geoff Levner <[hidden email]> wrote:
>
> On Alex's advice I am switching from MCJIT to the Orc API to compile and execute functions. Starting from the new clang-interpreter example in the source code (top of the tree!), I am able to execute my functions all right... as long as there are no constructors and destructors to call.
>
> My question: is there a simple way, with the Orc API, to run a module's constructors and destructors? I see how OrcMCJITReplacement does it, calling getConstructors() and getDestructors() when a module is added, and running them later using a layer, but is there maybe a simpler way that I am missing? I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
>
> Thanks,
> Geoff
>
> On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
> Hi Geoff,
>
> I hit the same problem some time ago.
> The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
> When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
> That's basically the reason of the crash.
>
> From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
> I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
> That function would record atexit handlers, which you can call manually after running your program.
> Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.
>
> I think this is the right place to ask such questions.
> Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.
>
> I hope it helps.
>
> Cheers,
> Alex.
>
> > On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
> >
> > Greetings, LLVM wizards.
> >
> > I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
> >
> > exec_engine->runStaticConstructorsDestructors(false);
> > exec_engine->runFunctionAsMain(function, argvec, NULL);
> >
> > execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
> >
> > This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
> >
> > Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
> >
> > Thanks,
> > Geoff

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

signature.asc (499 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
When OrcMCJITReplacement is given a new module, it asks for the module's constructors, gives them names like $static_ctor.0, $static_ctor.1, etc., and saves the mangled names in a map. Later, to execute them, it uses runViaLayer(), which looks for those symbol names in the given JIT layer. Could one not simply execute the constructors straight away, rather than naming them and looking them up by name later, if there is only one module?

On Wed, 20 Jun 2018 at 23:08, Alex Denisov <[hidden email]> wrote:
Hi Geoff,

As far as I know there is no "simple" way to do that.

> I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...

What do you mean by "invent secret names"? If you don't need to JIT native object files, but only bitcode, then MCJIT' approach should work. Just use that "snippet" in your code :)

> On 19. Jun 2018, at 17:54, Geoff Levner <[hidden email]> wrote:
>
> On Alex's advice I am switching from MCJIT to the Orc API to compile and execute functions. Starting from the new clang-interpreter example in the source code (top of the tree!), I am able to execute my functions all right... as long as there are no constructors and destructors to call.
>
> My question: is there a simple way, with the Orc API, to run a module's constructors and destructors? I see how OrcMCJITReplacement does it, calling getConstructors() and getDestructors() when a module is added, and running them later using a layer, but is there maybe a simpler way that I am missing? I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
>
> Thanks,
> Geoff
>
> On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
> Hi Geoff,
>
> I hit the same problem some time ago.
> The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
> When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
> That's basically the reason of the crash.
>
> From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
> I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
> That function would record atexit handlers, which you can call manually after running your program.
> Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.
>
> I think this is the right place to ask such questions.
> Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.
>
> I hope it helps.
>
> Cheers,
> Alex.
>
> > On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
> >
> > Greetings, LLVM wizards.
> >
> > I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
> >
> > exec_engine->runStaticConstructorsDestructors(false);
> > exec_engine->runFunctionAsMain(function, argvec, NULL);
> >
> > execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
> >
> > This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
> >
> > Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
> >
> > Thanks,
> > Geoff


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Now I see, thanks.

There is no need to do it exactly the same way as OrcMCJITReplacement does.
What you need is to get list of constructors and destructors functions from a module. You can just reuse this code snippet in your code:
https://github.com/llvm-mirror/llvm/blob/91b6092209489b4790826efc66fce178a6ec7f46/lib/ExecutionEngine/ExecutionEngine.cpp#L371

Then, before running main (or whatever else function you want to run) you just iterate through the list of constructors, ask JIT for a pointer to a constructor given it's mangled name, and just run it as you would run any other function.
After running main do the same for destructors.

We do it the same way and it seemed to be working (code is a bit messy, but you get the idea):
https://github.com/mull-project/mull/blob/master/lib/CustomTestFramework/CustomTestRunner.cpp#L71

I hope it helps.

Cheers,
Alex.

> On 21. Jun 2018, at 09:27, Geoff Levner <[hidden email]> wrote:
>
> When OrcMCJITReplacement is given a new module, it asks for the module's constructors, gives them names like $static_ctor.0, $static_ctor.1, etc., and saves the mangled names in a map. Later, to execute them, it uses runViaLayer(), which looks for those symbol names in the given JIT layer. Could one not simply execute the constructors straight away, rather than naming them and looking them up by name later, if there is only one module?
>
> On Wed, 20 Jun 2018 at 23:08, Alex Denisov <[hidden email]> wrote:
> Hi Geoff,
>
> As far as I know there is no "simple" way to do that.
>
> > I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
>
> What do you mean by "invent secret names"? If you don't need to JIT native object files, but only bitcode, then MCJIT' approach should work. Just use that "snippet" in your code :)
>
> > On 19. Jun 2018, at 17:54, Geoff Levner <[hidden email]> wrote:
> >
> > On Alex's advice I am switching from MCJIT to the Orc API to compile and execute functions. Starting from the new clang-interpreter example in the source code (top of the tree!), I am able to execute my functions all right... as long as there are no constructors and destructors to call.
> >
> > My question: is there a simple way, with the Orc API, to run a module's constructors and destructors? I see how OrcMCJITReplacement does it, calling getConstructors() and getDestructors() when a module is added, and running them later using a layer, but is there maybe a simpler way that I am missing? I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
> >
> > Thanks,
> > Geoff
> >
> > On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
> > Hi Geoff,
> >
> > I hit the same problem some time ago.
> > The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
> > When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
> > That's basically the reason of the crash.
> >
> > From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
> > I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
> > That function would record atexit handlers, which you can call manually after running your program.
> > Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.
> >
> > I think this is the right place to ask such questions.
> > Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.
> >
> > I hope it helps.
> >
> > Cheers,
> > Alex.
> >
> > > On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
> > >
> > > Greetings, LLVM wizards.
> > >
> > > I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
> > >
> > > exec_engine->runStaticConstructorsDestructors(false);
> > > exec_engine->runFunctionAsMain(function, argvec, NULL);
> > >
> > > execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
> > >
> > > This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
> > >
> > > Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
> > >
> > > Thanks,
> > > Geoff
>

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

signature.asc (499 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Many thanks for the sample code, Alex. In the end I did it the same way OrcMCJITReplacement does it. Constructors and destructors are called and, thanks to LocalCXXRuntimeOverrides, the program does not crash on exit! But it does seem like there should be a simpler way; the learning curve is steep...

Geoff

On Thu, 21 Jun 2018 at 12:28, Alex Denisov <[hidden email]> wrote:
Now I see, thanks.

There is no need to do it exactly the same way as OrcMCJITReplacement does.
What you need is to get list of constructors and destructors functions from a module. You can just reuse this code snippet in your code:
https://github.com/llvm-mirror/llvm/blob/91b6092209489b4790826efc66fce178a6ec7f46/lib/ExecutionEngine/ExecutionEngine.cpp#L371

Then, before running main (or whatever else function you want to run) you just iterate through the list of constructors, ask JIT for a pointer to a constructor given it's mangled name, and just run it as you would run any other function.
After running main do the same for destructors.

We do it the same way and it seemed to be working (code is a bit messy, but you get the idea):
https://github.com/mull-project/mull/blob/master/lib/CustomTestFramework/CustomTestRunner.cpp#L71

I hope it helps.

Cheers,
Alex.

> On 21. Jun 2018, at 09:27, Geoff Levner <[hidden email]> wrote:
>
> When OrcMCJITReplacement is given a new module, it asks for the module's constructors, gives them names like $static_ctor.0, $static_ctor.1, etc., and saves the mangled names in a map. Later, to execute them, it uses runViaLayer(), which looks for those symbol names in the given JIT layer. Could one not simply execute the constructors straight away, rather than naming them and looking them up by name later, if there is only one module?
>
> On Wed, 20 Jun 2018 at 23:08, Alex Denisov <[hidden email]> wrote:
> Hi Geoff,
>
> As far as I know there is no "simple" way to do that.
>
> > I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
>
> What do you mean by "invent secret names"? If you don't need to JIT native object files, but only bitcode, then MCJIT' approach should work. Just use that "snippet" in your code :)
>
> > On 19. Jun 2018, at 17:54, Geoff Levner <[hidden email]> wrote:
> >
> > On Alex's advice I am switching from MCJIT to the Orc API to compile and execute functions. Starting from the new clang-interpreter example in the source code (top of the tree!), I am able to execute my functions all right... as long as there are no constructors and destructors to call.
> >
> > My question: is there a simple way, with the Orc API, to run a module's constructors and destructors? I see how OrcMCJITReplacement does it, calling getConstructors() and getDestructors() when a module is added, and running them later using a layer, but is there maybe a simpler way that I am missing? I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
> >
> > Thanks,
> > Geoff
> >
> > On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
> > Hi Geoff,
> >
> > I hit the same problem some time ago.
> > The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
> > When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
> > That's basically the reason of the crash.
> >
> > From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
> > I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
> > That function would record atexit handlers, which you can call manually after running your program.
> > Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.
> >
> > I think this is the right place to ask such questions.
> > Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.
> >
> > I hope it helps.
> >
> > Cheers,
> > Alex.
> >
> > > On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
> > >
> > > Greetings, LLVM wizards.
> > >
> > > I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
> > >
> > > exec_engine->runStaticConstructorsDestructors(false);
> > > exec_engine->runFunctionAsMain(function, argvec, NULL);
> > >
> > > execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
> > >
> > > This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
> > >
> > > Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
> > >
> > > Thanks,
> > > Geoff
>


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Adding Lang here - in case he's got some ideas on this issue/plans to improve support.

On Mon, Jun 25, 2018 at 7:29 AM Geoff Levner via llvm-dev <[hidden email]> wrote:
Many thanks for the sample code, Alex. In the end I did it the same way OrcMCJITReplacement does it. Constructors and destructors are called and, thanks to LocalCXXRuntimeOverrides, the program does not crash on exit! But it does seem like there should be a simpler way; the learning curve is steep...

Geoff

On Thu, 21 Jun 2018 at 12:28, Alex Denisov <[hidden email]> wrote:
Now I see, thanks.

There is no need to do it exactly the same way as OrcMCJITReplacement does.
What you need is to get list of constructors and destructors functions from a module. You can just reuse this code snippet in your code:
https://github.com/llvm-mirror/llvm/blob/91b6092209489b4790826efc66fce178a6ec7f46/lib/ExecutionEngine/ExecutionEngine.cpp#L371

Then, before running main (or whatever else function you want to run) you just iterate through the list of constructors, ask JIT for a pointer to a constructor given it's mangled name, and just run it as you would run any other function.
After running main do the same for destructors.

We do it the same way and it seemed to be working (code is a bit messy, but you get the idea):
https://github.com/mull-project/mull/blob/master/lib/CustomTestFramework/CustomTestRunner.cpp#L71

I hope it helps.

Cheers,
Alex.

> On 21. Jun 2018, at 09:27, Geoff Levner <[hidden email]> wrote:
>
> When OrcMCJITReplacement is given a new module, it asks for the module's constructors, gives them names like $static_ctor.0, $static_ctor.1, etc., and saves the mangled names in a map. Later, to execute them, it uses runViaLayer(), which looks for those symbol names in the given JIT layer. Could one not simply execute the constructors straight away, rather than naming them and looking them up by name later, if there is only one module?
>
> On Wed, 20 Jun 2018 at 23:08, Alex Denisov <[hidden email]> wrote:
> Hi Geoff,
>
> As far as I know there is no "simple" way to do that.
>
> > I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
>
> What do you mean by "invent secret names"? If you don't need to JIT native object files, but only bitcode, then MCJIT' approach should work. Just use that "snippet" in your code :)
>
> > On 19. Jun 2018, at 17:54, Geoff Levner <[hidden email]> wrote:
> >
> > On Alex's advice I am switching from MCJIT to the Orc API to compile and execute functions. Starting from the new clang-interpreter example in the source code (top of the tree!), I am able to execute my functions all right... as long as there are no constructors and destructors to call.
> >
> > My question: is there a simple way, with the Orc API, to run a module's constructors and destructors? I see how OrcMCJITReplacement does it, calling getConstructors() and getDestructors() when a module is added, and running them later using a layer, but is there maybe a simpler way that I am missing? I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
> >
> > Thanks,
> > Geoff
> >
> > On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
> > Hi Geoff,
> >
> > I hit the same problem some time ago.
> > The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
> > When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
> > That's basically the reason of the crash.
> >
> > From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
> > I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
> > That function would record atexit handlers, which you can call manually after running your program.
> > Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.
> >
> > I think this is the right place to ask such questions.
> > Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.
> >
> > I hope it helps.
> >
> > Cheers,
> > Alex.
> >
> > > On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
> > >
> > > Greetings, LLVM wizards.
> > >
> > > I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
> > >
> > > exec_engine->runStaticConstructorsDestructors(false);
> > > exec_engine->runFunctionAsMain(function, argvec, NULL);
> > >
> > > execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
> > >
> > > This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
> > >
> > > Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
> > >
> > > Thanks,
> > > Geoff
>

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Hi All,

Alex -- thanks for stepping in!

Many thanks for the sample code, Alex. In the end I did it the same way OrcMCJITReplacement does it. Constructors and destructors are called and, thanks to LocalCXXRuntimeOverrides, the program does not crash on exit! But it does seem like there should be a simpler way; the learning curve is steep...

It is a bit. Some background, in case it helps: LLVM's JIT APIs are all based on re-using the static compiler pipeline and patching up relocatable object files in memory. That forces the JIT APIs to conform to linker rules. In particular, there is no way to refer to a private or anonymous symbol, which is why we have to name the constructors and make sure their linkage is promoted to external.

It would probably be reasonable to wrap all this up in a utility function though:

std::pair<CtorDtorRunner, CtorDtorRunner>
enableStaticConstructorsAndDestructors(Module &M);

I'll try that out.

Also worth noting here: I'm going to land a new ORC stack (tentatively called LLJIT) intended for general use in the next couple of days. It will replace the custom JIT stack currently buried in the LLI tool. If you are interested in trying it I will let you know when it lands, and I'd be happy to hear your feedback. :)

Cheers,
Lang.

On Mon, Jun 25, 2018 at 9:21 AM David Blaikie <[hidden email]> wrote:
Adding Lang here - in case he's got some ideas on this issue/plans to improve support.

On Mon, Jun 25, 2018 at 7:29 AM Geoff Levner via llvm-dev <[hidden email]> wrote:
Many thanks for the sample code, Alex. In the end I did it the same way OrcMCJITReplacement does it. Constructors and destructors are called and, thanks to LocalCXXRuntimeOverrides, the program does not crash on exit! But it does seem like there should be a simpler way; the learning curve is steep...

Geoff

On Thu, 21 Jun 2018 at 12:28, Alex Denisov <[hidden email]> wrote:
Now I see, thanks.

There is no need to do it exactly the same way as OrcMCJITReplacement does.
What you need is to get list of constructors and destructors functions from a module. You can just reuse this code snippet in your code:
https://github.com/llvm-mirror/llvm/blob/91b6092209489b4790826efc66fce178a6ec7f46/lib/ExecutionEngine/ExecutionEngine.cpp#L371

Then, before running main (or whatever else function you want to run) you just iterate through the list of constructors, ask JIT for a pointer to a constructor given it's mangled name, and just run it as you would run any other function.
After running main do the same for destructors.

We do it the same way and it seemed to be working (code is a bit messy, but you get the idea):
https://github.com/mull-project/mull/blob/master/lib/CustomTestFramework/CustomTestRunner.cpp#L71

I hope it helps.

Cheers,
Alex.

> On 21. Jun 2018, at 09:27, Geoff Levner <[hidden email]> wrote:
>
> When OrcMCJITReplacement is given a new module, it asks for the module's constructors, gives them names like $static_ctor.0, $static_ctor.1, etc., and saves the mangled names in a map. Later, to execute them, it uses runViaLayer(), which looks for those symbol names in the given JIT layer. Could one not simply execute the constructors straight away, rather than naming them and looking them up by name later, if there is only one module?
>
> On Wed, 20 Jun 2018 at 23:08, Alex Denisov <[hidden email]> wrote:
> Hi Geoff,
>
> As far as I know there is no "simple" way to do that.
>
> > I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
>
> What do you mean by "invent secret names"? If you don't need to JIT native object files, but only bitcode, then MCJIT' approach should work. Just use that "snippet" in your code :)
>
> > On 19. Jun 2018, at 17:54, Geoff Levner <[hidden email]> wrote:
> >
> > On Alex's advice I am switching from MCJIT to the Orc API to compile and execute functions. Starting from the new clang-interpreter example in the source code (top of the tree!), I am able to execute my functions all right... as long as there are no constructors and destructors to call.
> >
> > My question: is there a simple way, with the Orc API, to run a module's constructors and destructors? I see how OrcMCJITReplacement does it, calling getConstructors() and getDestructors() when a module is added, and running them later using a layer, but is there maybe a simpler way that I am missing? I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
> >
> > Thanks,
> > Geoff
> >
> > On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
> > Hi Geoff,
> >
> > I hit the same problem some time ago.
> > The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
> > When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
> > That's basically the reason of the crash.
> >
> > From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
> > I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
> > That function would record atexit handlers, which you can call manually after running your program.
> > Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.
> >
> > I think this is the right place to ask such questions.
> > Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.
> >
> > I hope it helps.
> >
> > Cheers,
> > Alex.
> >
> > > On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
> > >
> > > Greetings, LLVM wizards.
> > >
> > > I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
> > >
> > > exec_engine->runStaticConstructorsDestructors(false);
> > > exec_engine->runFunctionAsMain(function, argvec, NULL);
> > >
> > > execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
> > >
> > > This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
> > >
> > > Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
> > >
> > > Thanks,
> > > Geoff
>

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] runStaticConstructorsDestructors() causes crash on exit

Muhui Jiang via llvm-dev
Initial implementations of LLJIT and LLLazyJIT are available as of r335670.

The runOrcLazyJIT function in lli.cpp shows example usage that includes (1), reflecting symbols from the process itself into the JIT symbol tables, (2) enabling CXX runtime overrides, (3) adding modules for lazy compilation, and (4) running static constructors and destructors.

Hope this helps!

Cheers,
Lang.


On Mon, Jun 25, 2018 at 7:31 PM Lang Hames <[hidden email]> wrote:
Hi All,

Alex -- thanks for stepping in!

Many thanks for the sample code, Alex. In the end I did it the same way OrcMCJITReplacement does it. Constructors and destructors are called and, thanks to LocalCXXRuntimeOverrides, the program does not crash on exit! But it does seem like there should be a simpler way; the learning curve is steep...

It is a bit. Some background, in case it helps: LLVM's JIT APIs are all based on re-using the static compiler pipeline and patching up relocatable object files in memory. That forces the JIT APIs to conform to linker rules. In particular, there is no way to refer to a private or anonymous symbol, which is why we have to name the constructors and make sure their linkage is promoted to external.

It would probably be reasonable to wrap all this up in a utility function though:

std::pair<CtorDtorRunner, CtorDtorRunner>
enableStaticConstructorsAndDestructors(Module &M);

I'll try that out.

Also worth noting here: I'm going to land a new ORC stack (tentatively called LLJIT) intended for general use in the next couple of days. It will replace the custom JIT stack currently buried in the LLI tool. If you are interested in trying it I will let you know when it lands, and I'd be happy to hear your feedback. :)

Cheers,
Lang.

On Mon, Jun 25, 2018 at 9:21 AM David Blaikie <[hidden email]> wrote:
Adding Lang here - in case he's got some ideas on this issue/plans to improve support.

On Mon, Jun 25, 2018 at 7:29 AM Geoff Levner via llvm-dev <[hidden email]> wrote:
Many thanks for the sample code, Alex. In the end I did it the same way OrcMCJITReplacement does it. Constructors and destructors are called and, thanks to LocalCXXRuntimeOverrides, the program does not crash on exit! But it does seem like there should be a simpler way; the learning curve is steep...

Geoff

On Thu, 21 Jun 2018 at 12:28, Alex Denisov <[hidden email]> wrote:
Now I see, thanks.

There is no need to do it exactly the same way as OrcMCJITReplacement does.
What you need is to get list of constructors and destructors functions from a module. You can just reuse this code snippet in your code:
https://github.com/llvm-mirror/llvm/blob/91b6092209489b4790826efc66fce178a6ec7f46/lib/ExecutionEngine/ExecutionEngine.cpp#L371

Then, before running main (or whatever else function you want to run) you just iterate through the list of constructors, ask JIT for a pointer to a constructor given it's mangled name, and just run it as you would run any other function.
After running main do the same for destructors.

We do it the same way and it seemed to be working (code is a bit messy, but you get the idea):
https://github.com/mull-project/mull/blob/master/lib/CustomTestFramework/CustomTestRunner.cpp#L71

I hope it helps.

Cheers,
Alex.

> On 21. Jun 2018, at 09:27, Geoff Levner <[hidden email]> wrote:
>
> When OrcMCJITReplacement is given a new module, it asks for the module's constructors, gives them names like $static_ctor.0, $static_ctor.1, etc., and saves the mangled names in a map. Later, to execute them, it uses runViaLayer(), which looks for those symbol names in the given JIT layer. Could one not simply execute the constructors straight away, rather than naming them and looking them up by name later, if there is only one module?
>
> On Wed, 20 Jun 2018 at 23:08, Alex Denisov <[hidden email]> wrote:
> Hi Geoff,
>
> As far as I know there is no "simple" way to do that.
>
> > I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
>
> What do you mean by "invent secret names"? If you don't need to JIT native object files, but only bitcode, then MCJIT' approach should work. Just use that "snippet" in your code :)
>
> > On 19. Jun 2018, at 17:54, Geoff Levner <[hidden email]> wrote:
> >
> > On Alex's advice I am switching from MCJIT to the Orc API to compile and execute functions. Starting from the new clang-interpreter example in the source code (top of the tree!), I am able to execute my functions all right... as long as there are no constructors and destructors to call.
> >
> > My question: is there a simple way, with the Orc API, to run a module's constructors and destructors? I see how OrcMCJITReplacement does it, calling getConstructors() and getDestructors() when a module is added, and running them later using a layer, but is there maybe a simpler way that I am missing? I would prefer to avoid having to invent secret names for constructors, play with their linkage and visibility, and generally get involved in things I don't understand...
> >
> > Thanks,
> > Geoff
> >
> > On Fri, 15 Jun 2018 at 11:23, Alex Denisov <[hidden email]> wrote:
> > Hi Geoff,
> >
> > I hit the same problem some time ago.
> > The problem that atexit handlers are registered from the JITted code, and the handlers point to the memory allocated by JIT.
> > When the host program exits it calls the atexit handlers, but the memory is already deallocated by JIT.
> > That's basically the reason of the crash.
> >
> > From what I see ExecutionEngine and MCJIT do not provide any helpful API for this case.
> > I can only recommend switching to Orc APIs in this case: there you can use custom symbol resolver and redirect atexit functions to your own function(s).
> > That function would record atexit handlers, which you can call manually after running your program.
> > Orc APIs even provide a class for that: orc::LocalCXXRuntimeOverrides.
> >
> > I think this is the right place to ask such questions.
> > Otherwise, feel free to ping me on #llvm (AlexDenisov) if you need some hints on how to JIT native code using Orc APIs.
> >
> > I hope it helps.
> >
> > Cheers,
> > Alex.
> >
> > > On 14. Jun 2018, at 12:44, Geoff Levner via llvm-dev <[hidden email]> wrote:
> > >
> > > Greetings, LLVM wizards.
> > >
> > > I am using clang to compile a C++ module, and an ExecutionEngine (MCJIT) to execute a function it defines. That works (or pretends to). However, if I call the module's constructors first:
> > >
> > > exec_engine->runStaticConstructorsDestructors(false);
> > > exec_engine->runFunctionAsMain(function, argvec, NULL);
> > >
> > > execution still works, but my program crashes when it exits, in __run_exit_handlers(). I can't tell from gdb what exit handler is crashing, but no calls are made to atexit() or on_exit(); all exit handlers are installed via __cxa_atexit().
> > >
> > > This may or may not be meaningful, but I am forced to compile with -fno-use-cxa-atexit, otherwise clang complains that __dso_handle could not be resolved.
> > >
> > > Any guidance would be MUCH appreciated. I am at a loss... Also, if you know of a better place to look for help than this mailing list, that would be appreciated, too.
> > >
> > > Thanks,
> > > Geoff
>

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev