backward-cpp
backward-cpp copied to clipboard
Usage on Windows with MinGW
Preface
I looked through the code and saw that at Line 897 it says that StackWalk64 only works when using PDBs, and from what I could tell there aren't any other Windows specific StackTraceImpl that handle GCC or Clang (on Windows). Obviously, GCC doesn't produce PDBs and rather uses DWARF inside of the executable. It's reasonable to assume that is true for MinGW since it's built on top of GCC. Looking further into it, it doesn't attempt to use libgcc or (e)glib both of which should be present on an MinGW installation (libgcc is definitely present).
Question
How would I go about using the library in this situation? I looked at #50 hoping that there was some talk about this, but it was strictly implementation, of which seems to only have included MSVC.
Looks like there is a distinction between GNU vs MS Windows then. There might be a way to set the #ifdef in such a ways, that if Windows + MingGW then it uses DWARF implementation.
I think the problem is not only this. I just tried building backward.hpp and got a few errors. Used the MinGW 810 from Qt compiler.
backward-cpp/backward.hpp:316: warning: "NOMINMAX" redefined
#define NOMINMAX
In file included from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h:508,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/type_traits:38,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/qglobal.h:45,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/QtCore:4,
from C:/Qt/5.15.0/mingw81_64/include/QtTest/QtTestDepends:3,
from C:/Qt/5.15.0/mingw81_64/include/QtTest/QtTest:3,
from tst_deploytest.cpp:8:
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32/bits/os_defines.h:45: note: this is the location of the previous definition
#define NOMINMAX 1
In file included from tst_deploytest.cpp:32:
backward-cpp/backward.hpp:328: warning: ignoring #pragma comment [-Wunknown-pragmas]
#pragma comment(lib, "psapi.lib")
backward-cpp/backward.hpp:329: warning: ignoring #pragma comment [-Wunknown-pragmas]
#pragma comment(lib, "dbghelp.lib")
In file included from tst_deploytest.cpp:32:
backward-cpp/backward.hpp: In member function 'backward::module_data backward::get_mod_info::operator()(HMODULE)':
backward-cpp/backward.hpp:3303:42: error: cannot convert 'char*' to 'LPWSTR' {aka 'wchar_t*'}
GetModuleFileNameEx(process, module, temp, sizeof(temp));
^~~~
In file included from backward-cpp/backward.hpp:320,
from tst_deploytest.cpp:32:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/Psapi.h:80:76: note: initializing argument 3 of 'DWORD GetModuleFileNameExW(HANDLE, HMODULE, LPWSTR, DWORD)'
DWORD WINAPI GetModuleFileNameExW(HANDLE hProcess,HMODULE hModule,LPWSTR lpFilename,DWORD nSize);
~~~~~~~^~~~~~~~~~
In file included from tst_deploytest.cpp:32:
backward-cpp/backward.hpp:3305:40: error: cannot convert 'char*' to 'LPWSTR' {aka 'wchar_t*'}
GetModuleBaseName(process, module, temp, sizeof(temp));
^~~~
In file included from backward-cpp/backward.hpp:320,
from tst_deploytest.cpp:32:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/Psapi.h:78:74: note: initializing argument 3 of 'DWORD GetModuleBaseNameW(HANDLE, HMODULE, LPWSTR, DWORD)'
DWORD WINAPI GetModuleBaseNameW(HANDLE hProcess,HMODULE hModule,LPWSTR lpBaseName,DWORD nSize);
~~~~~~~^~~~~~~~~~
In file included from tst_deploytest.cpp:32:
backward-cpp/backward.hpp: In member function 'backward::ResolvedTrace backward::TraceResolverImpl<backward::system_tag::windows_tag>::resolve(backward::ResolvedTrace)':
backward-cpp/backward.hpp:3370:14: error: cannot convert 'LPTSTR' {aka 'wchar_t*'} to 'const char*'
printf(lpMsgBuf);
^~~~~~~~
In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/locale.h:12,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/clocale:42,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/x86_64-w64-mingw32/bits/c++locale.h:41,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/localefwd.h:40,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:43,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/qbytearray.h:52,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/qstring.h:50,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/qobject.h:47,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/qabstractanimation.h:43,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/QtCore:6,
from C:/Qt/5.15.0/mingw81_64/include/QtTest/QtTestDepends:3,
from C:/Qt/5.15.0/mingw81_64/include/QtTest/QtTest:3,
from tst_deploytest.cpp:8:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/stdio.h:345:25: note: initializing argument 1 of 'int printf(const char*, ...)'
int printf (const char *__format, ...)
~~~~~~~~~~~~^~~~~~~~
In file included from tst_deploytest.cpp:32:
backward-cpp/backward.hpp: In constructor 'backward::SignalHandling::SignalHandling(const std::vector<int, std::allocator<int> >&)':
backward-cpp/backward.hpp:4019:5: error: 'set_terminate' was not declared in this scope
set_terminate(&terminator);
^~~~~~~~~~~~~
backward-cpp/backward.hpp:4019:5: note: suggested alternative:
In file included from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/new:40,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_construct.h:59,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_tempbuf.h:60,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:62,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/algorithm:62,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/qglobal.h:142,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/QtCore:4,
from C:/Qt/5.15.0/mingw81_64/include/QtTest/QtTestDepends:3,
from C:/Qt/5.15.0/mingw81_64/include/QtTest/QtTest:3,
from tst_deploytest.cpp:8:
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/exception:67:21: note: 'std::set_terminate'
terminate_handler set_terminate(terminate_handler) _GLIBCXX_USE_NOEXCEPT;
^~~~~~~~~~~~~
In file included from tst_deploytest.cpp:32:
backward-cpp/backward.hpp:4020:5: error: 'set_unexpected' was not declared in this scope
set_unexpected(&terminator);
^~~~~~~~~~~~~~
backward-cpp/backward.hpp:4020:5: note: suggested alternative:
In file included from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/new:40,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_construct.h:59,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_tempbuf.h:60,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_algo.h:62,
from C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/algorithm:62,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/qglobal.h:142,
from C:/Qt/5.15.0/mingw81_64/include/QtCore/QtCore:4,
from C:/Qt/5.15.0/mingw81_64/include/QtTest/QtTestDepends:3,
from C:/Qt/5.15.0/mingw81_64/include/QtTest/QtTest:3,
from tst_deploytest.cpp:8:
C:/Qt/Tools/mingw810_64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/exception:79:22: note: 'std::set_unexpected'
unexpected_handler set_unexpected(unexpected_handler) _GLIBCXX_USE_NOEXCEPT;
^~~~~~~~~~~~~~
It seems to compile fine on Mingw-w64 8.1.0, but does not actually do anything.
You have to enable the stack walking and symbol resolver library/API to use. The "unwind" API is provided by GCC, and this might provide stack walking at least. Look at the preprocessor "defines" atop backward.hpp
On Fri, 27 Nov 2020, 13:15 Vadim Peretokin, [email protected] wrote:
It seems to compile fine on Mingw-w64 8.1.0, but does not actually do anything.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bombela/backward-cpp/issues/176#issuecomment-734991334, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABUZDEI6NZRPXO5DXI2ZWTSSAJHTANCNFSM4ONSHS6Q .
@EndrII With the following patch applied on release 1.5, I got that release building on mingw on Linux: This pach is compatible with MSVC because Windows filesystems are case insensitive.
--- backward.hpp
+++ backward.hpp
@@ -313,1 +313,1 @@
-#include <BaseTsd.h>
+#include <basetsd.h>
@@ -317,1 +317,1 @@
-#include <Windows.h>
+#include <windows.h>
@@ -320,1 +320,1 @@
-#include <Psapi.h>
+#include <psapi.h>
@@ -4017,2 +4017,2 @@
- set_terminate(&terminator);
- set_unexpected(&terminator);
+ std::set_terminate(&terminator);
+ std::set_unexpected(&terminator);
Note: this patch is used at https://github.com/conan-io/conan-center-index/pull/6665
I opened a pr to add mingw support, when building on Linux. See https://github.com/bombela/backward-cpp/pull/234
Hello world, Is there still any live issue here? I ask because I just used <unwind.h> + libbfd successfully to give another project backtraces with line numbers on Linux+Windows+macOS. (MSVC support was a non-goal. Good traces into macOS dylibs was also a non-goal.) I think I could do the same for this project, but it might be a mistake if your existing Windows implementation is MinGW-compatible and fully functional already...
Hi,
After trying many many things, I've managed to compile a test program on windows using mingw and gcc (g++). It only compiled with linking with msvcr90. But When I do, I don't see any output.
rm -fr backward.o main.o main main.exe
g++.exe -g -c backward.cpp
g++.exe -g -c main.cpp
g++.exe -o main backward.o main.o -mconsole -lmsvcr90 -ldbghelp -lpsapi
./main.exe
Has someone managed to make it work in this scenario?
Here is a minimal repository to reproduce the issue: https://github.com/ArnaudValensi/test-stacktrace/tree/85e427c5d4ad15b49821d8c4b190904f5d649ad3
For linux I have no issue, everything works perfectly.
PS: @UncombedCoconut I'm trying to do exactly what you've done.
Hi, After trying many many things, I've managed to compile a test program on windows using mingw and gcc (g++). It only compiled with linking with
msvcr90. But When I do, I don't see any output.rm -fr backward.o main.o main main.exe g++.exe -g -c backward.cpp g++.exe -g -c main.cpp g++.exe -o main backward.o main.o -mconsole -lmsvcr90 -ldbghelp -lpsapi ./main.exeHas someone managed to make it work in this scenario?
Here is a minimal repository to reproduce the issue: https://github.com/ArnaudValensi/test-stacktrace
For linux I have no issue, everything works perfectly.
PS: @UncombedCoconut I'm trying to do exactly what you've done.
OK! If you prefer to try alternatives before waiting for a patch to "backward" (my offer is open, but not immediately and I don't know if the project is interested :)) I'd suggest trying https://github.com/ianlancetaylor/libbacktrace/. That works very similarly to what I proposed. (Apologies to this project for plugging a competing one. Both are very nice.)
Thanks for the suggestions, actually I also tried libbacktrack but it doesn't handle mingw on windows. See my issue here https://github.com/ianlancetaylor/libbacktrace/issues/103
@UncombedCoconut would you accept to share me an example of unwind + libbfd working with mingw? 🙏
I've managed to make it work with clang on mingw. On linux, backward handles ELF executable with DWARF debug symbols. On windows, it handles PE executable with PDB (codeview) debug symbols. The thing is that with mingw on windows, gcc and clang create PE executable but with DWARF symbols. Fortunately, it's possible to generate PDB with clang, but for that we need to use lld as a linker, instead of the default ld linker:
clang++.exe -g -gcodeview -c backward.cpp
clang++.exe -g -gcodeview -c main.cpp
clang++.exe -o main *.o -ldbghelp -lucrt -Wl,--pdb= -fuse-ld=lld
-g -gcodeviewis required to generate all the debug info that will be used by the linker to generate the PDB.-Wl,--pdb=tells clang to forwad the parameter--pdb=to the linker (lld)-fuse-ld=lldtells clang to use lld instead of ld (you might need to install it:pacman -S mingw-w64-x86_64-lld)-ldbghelplinks to dbghelp which is needed for some functions used by backward-lucrtis needed for the following function in backward: https://github.com/bombela/backward-cpp/blob/90398eef20f4e7e0e939322d7e84f9c52078a325/backward.hpp#L4338
But linking with ucrt can create some complications if you also link with some library that was compiled with another *rt library. In this case, I think we can safely remove the call of _set_abort_behavior because I guess it just disable some default output when aborting (https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/set-abort-behavior?view=msvc-170).
Here is a minimal working example https://github.com/ArnaudValensi/test-stacktrace/tree/7fcfc0179a55ebd50027d8789c5010ac3c62d73c
Here some documentation about using PDB with clang: https://github.com/mstorsjo/llvm-mingw#pdb-support
As a final note, I think we could avoid doing all of this if we do as @bombela suggested: "There might be a way to set the #ifdef in such a ways, that if Windows + MingGW then it uses DWARF implementation."