Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error and crash related to using inside a DLL #147

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

SamWindell
Copy link

This fixes 2 issues I was having when using libbacktrace inside a Window DLL.

  • Instead of GetModuleHandle (NULL), pass in the filename so we get the correct base address regardless of if we're running in a EXE or DLL. Before this patch, all debug symbol lookups within a 'main' DLL were offset by the base address of the parent process - giving nonsense.
  • Only register for DLL added notifications if we are an EXE. We can't support this from inside a DLL without having a way to unregister the notification prior to our running DLL being unloaded. Before this fix we would get crashes related to calling registered functions that are no longer loaded.

SamWindell and others added 2 commits January 31, 2025 21:25
When libbacktrace is used directly in a DLL (for example backtrace_create_state is being called DllMain), we can't use GetModuleHandle(NULL) since that returns the module handle of the calling process (executable) and so all our lookups are incorrect. 

Instead, we can use the same function, but pass in the filepath that we already have. This fixes the DLL issue and still works for EXEs.
This fixes and issue when libbacktrace is used inside a DLL - where
libbacktrace is initialised in DllMain, for example.

If the module is a DLL itself, we shouldn't register for DLL
notifications - that is the job of the executing processing, not of one
of it's modules. Prior to this patch, there can be crashes when using
libbacktrace directly from DLL due to notifications being sent to
invalid addresses.

GetModuleHandle(NULL) returns the handle of the process - so we can use
that alongside our already existing module handle to determine if we are
running as a DLL or EXE.
@ianlancetaylor
Copy link
Owner

CC @HazardyKnusperkeks

@HazardyKnusperkeks
Copy link

This fixes 2 issues I was having when using libbacktrace inside a Window DLL.

* Instead of GetModuleHandle (NULL), pass in the filename so we get the correct base address regardless of if we're running in a EXE or DLL. Before this patch, all debug symbol lookups within a 'main' DLL were offset by the base address of the parent process - giving nonsense.

Although I directly linked libbacktrace while making these changes, my main usage is through a DLL and I get the correct names and line numbers for functions from the exe and the DLL. Do you have an example I can look at?

* Only register for DLL added notifications if we are an EXE. We can't support this from inside a DLL without having a way to unregister the notification prior to our running DLL being unloaded. Before this fix we would get crashes related to calling registered functions that are no longer loaded.

It's correct, that there could be crashes, but as stated the usage from a DLL is my main usage. I think we should look for a compromise.

And I don't use libbacktrace directly, but std::stack_trace from libstdc++.

@SamWindell
Copy link
Author

My use case is in an audio plugin, which is just a shared library binary. The host application is nothing to do with me and just calls into my functions. The host does have a standard API for calling me with init()/deinit() though, where I can set up some error reporting for my own code - this is where I initialise libbacktrace.

Is that the same use case you have @HazardyKnusperkeks? Just want to check if it's the same because you say you've always had correct file and line numbers.

@HazardyKnusperkeks
Copy link

No, I write the application and the libraries. Logging is a library, which then uses std::stacktrace on some occasions, and that is implemented using libbacktrace. In my use case the library is a dll, but directly linked (and thus will never be unloaded before the application ends). You will be loaded using LoadLibrary, right? I will set up a test to see what happens.

@SamWindell
Copy link
Author

Yes that's right, my audio plugin will be loaded with LoadLibrary. I am also using DWARF info rather than PDB, I'm not sure if that's relevant. My windows DLL is compiled with clang with the -gdwarf flag to embed the DWARF info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants