ianlancetaylor / libbacktrace

A C library that may be linked into a C/C++ program to produce symbolic backtraces
Other
935 stars 218 forks source link

mingw issue with executable path #42

Closed ambitslix closed 1 month ago

ambitslix commented 4 years ago

Getting the following error from callback after backtrace_full:

static void
ErrorCallback(void* data, const char* message, int err)

executable file is not COFF (0)
failed to read executable information (-1)

Then it it's an infinite loop of last error. Under Linux it runs fine.

Environment:

Statically linked executable ExceptionTest.exe: PE32+ executable (console) x86-64, for MS Windows OS:Ubuntu/Wine MXE static compiler

Any clues?

ianlancetaylor commented 4 years ago

What are the first 20 bytes of the file?

ambitslix commented 4 years ago

To clarify, the test and log is from a Windows 10 build with msys2 mingw64 compiler. I haven't been able to get the tests (make check) build under Linux mingw64 cross compiler. I will try to build the app under msys2 to see if there's different behaviour...

test-suite.log

make  check-TESTS
make[1]: Entering directory '/home/alian/Desktop/Projects/swan-framework/submodules/libbacktrace'
make[2]: Entering directory '/home/alian/Desktop/Projects/swan-framework/submodules/libbacktrace'
FAIL: allocfail.sh
PASS: test_elf_32.exe
PASS: test_elf_64.exe
PASS: test_xcoff_32.exe
PASS: test_xcoff_64.exe
PASS: test_pecoff.exe
PASS: test_unknown.exe
PASS: unittest.exe
PASS: unittest_alloc.exe
FAIL: btest.exe
FAIL: btest_alloc.exe
PASS: stest.exe
PASS: stest_alloc.exe
FAIL: edtest.exe
FAIL: edtest_alloc.exe
PASS: ttest.exe
PASS: ttest_alloc.exe
FAIL: dwarf5.exe
FAIL: dwarf5_alloc.exe
============================================================================
Testsuite summary for package-unused version-unused
============================================================================
# TOTAL: 19
# PASS:  12
# SKIP:  0
# XFAIL: 0
# FAIL:  7
# XPASS: 0
# ERROR: 0
============================================================================
See ./test-suite.log
============================================================================
make[2]: *** [Makefile:1533: test-suite.log] Error 1
make[2]: Leaving directory '/home/alian/Desktop/Projects/swan-framework/submodules/libbacktrace'
make[1]: *** [Makefile:1641: check-TESTS] Error 2
make[1]: Leaving directory '/home/alian/Desktop/Projects/swan-framework/submodules/libbacktrace'
make: *** [Makefile:1891: check-am] Error 2

Screenshot from 2020-05-16 19-53-20

Let me know, and I will send you the executable if that helps.

ianlancetaylor commented 4 years ago

Thanks. The start of that file looks fine. I don't see how it could produce that error.

Can you run it under the debugger and see what is happening? The error is being returned by the function coff_add in pecoff.c.

ambitslix commented 4 years ago

I ran it under the debugger, but it had errors before it got to that error, so I decided to reduce the complexity and used an example program that has minimal complexity and corrected for passing the executable path to backtrace_create which was suspect. So now I'm just still seeing no trace but no errors. However not to run too far ahead looking at btest nothing works:

$ ./btest.exe
FAIL: backtrace_full noinline
FAIL: backtrace_full inline
FAIL: backtrace_simple noinline
FAIL: backtrace_simple inline
test1: [0]: missing file name or function name
test2: [0]: missing file name or function name
test3: [0]: missing file name or function name
test3: [0]: NULL syminfo name
test3: [1]: NULL syminfo name
test3: [2]: NULL syminfo name
test4: [0]: missing file name or function name

Is this meant to work under Mingw / MSVC? Either way I think btest.c is the place to start looking for the problems? I guess it won't work with MS compiler as it uses gcc specifics.

matanui159 commented 4 years ago

I did a bit of a code dive and the problem seems to be that /proc/self/exe is the first valid executable filename, which just happens to point to the wine process instead of the current process.

matanui159 commented 4 years ago

Some more notes before i head to bed.

ambitslix commented 4 years ago

@matanui159 To clarify the initial problem didn't had to do with GetModuleFileName. It had to do with the variable passed to backtrace_create_state which in my case was temporary for some reason. Now both argv[0] and GetModuleFileName work under both wine and msys2 under Windows. They both return the same path under wine and msys2 for me, and they're windows paths. So that doesn't seem to be the problem anymore, and wasn't the problem in the case of btest.c.

  1. So backtrace_state should copy the exec path passed to backtrace_create_state for one thing. I tried to debug btest.c in msys2 but could not yet find why there is no backtrace.

  2. Also tests do not build under cross-compiler with make check

matanui159 commented 4 years ago

Also as a side note I noticed that if it fails to open the provided filename it falls back to alternatives. It would be nice if it failed with an error straight away if it couldn't open the provided filename since it would make issues like this easier to debug.

ambitslix commented 4 years ago

Yes I agree @matanui159. I'm opening another issue for the remaining problem which is that with mingw the library doesn't work.

matanui159 commented 4 years ago

I'll probably keep looking into that today although it will be slightly biased since I'm running it under wine on Linux. I really wanna get this project working, it's a really neat little library.

krlmlr commented 3 years ago

FWIW, whereami might be a more robust way to automatically determine the executable file name. This also works on MSYS2/Windows: https://github.com/gpakosz/whereami.

lurobi commented 3 years ago

Commenting on this to raise awareness, and see if a work-around can be identified. I'm using Gfortran 9.2 on msys2/mingw64 and it exhibits what may be the same problem. In my case when a segfault is issued, gfortran runtime uses libbacktrace to print the stack. The result I see on windows msys2/mingw64 is the following:

Error termination. Backtrace:

Could not print backtrace: libbacktrace could not find executable to open
#0  0xffffffff
#1  0xffffffff
#2  0xffffffff
....
#19  0xffffffff

I don't observe any infinite loop. It stops at #19.

ianlancetaylor commented 1 month ago

This was most likely fixed by c1c86fa2. Please comment if it is still a problem. Thanks.