Stacktrace dla aplikacji Windows, ale nie skompilowanej w msvc

0

Ktoś może wie jak na platformie msys2 uzyskać stacktrace z numerami linii ?
Chciałbym do logów zapisać stacktrace w momencie pojawienia się problemu

#include <iostream>
#include <boost/stacktrace.hpp>

int nested_func(int c)
{
    std::cout << boost::stacktrace::stacktrace();
    return c + 1;
}

int func(int b)
{
    return nested_func(b + 1);
}
 
int main()
{
    func(777);
}

Wynik działania bez zmiany parametrów kompilacji:

>  0# 0x00007FF610BF1C03 in D:\pulpit\gity\build\statctrace_std.exe
>  1# 0x00007FF610BF13D6 in D:\pulpit\gity\build\statctrace_std.exe
>  2# 0x00007FF610BF1454 in D:\pulpit\gity\build\statctrace_std.exe
>  3# 0x00007FF610BF1479 in D:\pulpit\gity\build\statctrace_std.exe
>  4# 0x00007FF610BF1315 in D:\pulpit\gity\build\statctrace_std.exe
>  5# 0x00007FF610BF1366 in D:\pulpit\gity\build\statctrace_std.exe
>  6# 0x00007FFAD01526AD in C:\WINDOWS\System32\KERNEL32.DLL
>  7# 0x00007FFAD170A9F8 in C:\WINDOWS\SYSTEM32\ntdll.dll

dodaje BOOST_STACKTRACE_USE_BACKTRACE + -lbacktrace

>  0# strncmp in D:\pulpit\gity\_us\build\statctrace_std.exe
>  1# strncmp in D:\pulpit\gity\_us\build\statctrace_std.exe
>  2# strncmp in D:\pulpit\gity\_us\build\statctrace_std.exe
>  3# strncmp in D:\pulpit\gity\_us\build\statctrace_std.exe
>  4# strncmp in D:\pulpit\gity\_us\build\statctrace_std.exe
>  5# strncmp in D:\pulpit\gity\_us\build\statctrace_std.exe
>  6# strncmp in C:\WINDOWS\System32\KERNEL32.DLL
>  7# strncmp in C:\WINDOWS\SYSTEM32\ntdll.dll
2

Z numerami linii czego? Jeśli z numerami linii pliki źródłowego to std::source_location jeśli masz C++20 a jak nie, to masz do dyspozycji makra _ _FILE_ _ i _ _LINE_ _.

4

Tu jest ciekawy wątek o różnych metodach śledzenia od C++-23 po C StackOverflow

Poza tym niektóre metody wykorzystują np. symbole debugera lub po prostu exportuja wszystkie funkcje, żeby były widoczne(metadane zwykle są tracone) lub jeszcze inaczej.

1

@GodOfCode.: dziekuje za materiały , sugestie i uwagi, widzę że powróciłeś z banicji

Przez przypadek trafiłem na ten projekt https://github.com/ssbssa/dwarfstack i tutaj to działa np.

wynik dzialania tego przykąłdu https://github.com/ssbssa/dwarfstack/blob/master/examples/location/location.c

base address: 0x00007FF6950B0000 (location.exe)
    stack 00: 0x00007FF6950B143D (obj2.c:61:3) [obj2func2]
    stack 01: 0x00007FF6950B1418 (obj2.c:66:3) [obj2func]
    stack 02: 0x00007FF6950B13A8 (location.c:14:3) [d]
    stack 03: 0x00007FF6950B13B8 (location.c:19:3) [c]
    stack 04: 0x00007FF6950B13C8 (location.c:24:3) [b]
    stack 05: 0x00007FF6950B13D8 (location.c:29:3) [a]
    stack 06: 0x00007FF6950B13FA (location.c:34:3) [main]
    stack 07: 0x00007FF6950B1314 (crtexe.c:267:15) [__tmainCRTStartup]
    stack 08: 0x00007FF6950B1365 (crtexe.c:188:9) [mainCRTStartup]

Pozostała z problemami:

  • C++23 <stacktrace> = choc mam clang 16.0.5 to na Windows jeszcze to nie dotarło, nie ma tego pliku
  • Boost stacktrace() = nie wyświetla ani nazw funkcji ani linii kodu na Windows
  • libbacktrace , działa podobnie jak boost, czyli ani nazw funkcji ani linii kodu na Windows, a w sumie boost uzywa tej biblioteki wiec i wynik nie dziwi
  • https://github.com/Febbe/stacktrace nazwy funkcji są zagmatwane przez manglowanie ale wyświetla poprawne linie kodu (brak demanglingu) , z nie działających działa najlepiej ;)
3

Demangling dość łatwo się robi demangling_abi.
Z tego co widzę po nazwie dwarf, czyli program musi sam siebie otwierać(tzn. chyba domyślnie sekcja debug nie jest ładowana do pamięci więc nie będzie bezpośrednio dostępu) i parsować debug symbole, czyli bez debug symboli nie pokaże prawidłowo.

Boost na windowsa widzę, że ma jakieś specjalne konfiguracje i trzeba windbg użyć pewnie z msvc kompilatorem i makrami doc.

W C++23 dość ciekawie wygląda bez użycia symboli debuggera, warte chyba obejrzenia, na templatach godbolt.

0

@GodOfCode.: dziękuje za przykład na godbold, ja nie wpadłem na to że to trzeba trunk-a, czyli <stacktrace> to na ten moment raczej ciekawostka

2

Ok w końcu rozgryzłem jak zmusić do działania na MSVC (copy paste z mojej konsoli):

C:\Users\marekR22\Downloads\stackTraceTest>cl main.cpp /std:c++20 /EHsc /Zi /Od /I F:\repos\component\Shared\ThirdParty\boost /D BOOST_STACKTRACE_USE_WINDBG
Microsoft (R) C/C++ Optimizing Compiler Version 19.34.31933 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
Microsoft (R) Incremental Linker Version 14.34.31933.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:main.exe
/debug
main.obj

C:\Users\marekR22\Downloads\stackTraceTest>main.exe
 0# boost::stacktrace::basic_stacktrace<std::allocator<boost::stacktrace::frame> >::init at F:\repos\component\Shared\ThirdParty\boost\boost\stacktrace\stacktrace.hpp:77
 1# boost::stacktrace::basic_stacktrace<std::allocator<boost::stacktrace::frame> >::basic_stacktrace<std::allocator<boost::stacktrace::frame> > at F:\repos\component\Shared\ThirdParty\boost\boost\stacktrace\stacktrace.hpp:130
 2# nested_func at C:\Users\marekR22\Downloads\stackTraceTest\main.cpp:6
 3# func at C:\Users\marekR22\Downloads\stackTraceTest\main.cpp:13
 4# main at C:\Users\marekR22\Downloads\stackTraceTest\main.cpp:18
 5# __scrt_common_main_seh at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
 6# BaseThreadInitThunk in KERNEL32
 7# RtlUserThreadStart in ntdll

/Zi pozwala na nazwanie sensownie funkcji i numery linii.
Trzeba też uważać na optymalizacje by nie skróciły call stack.

0

Aktualizacja: zmienił mi się faworyt :D
udało mi się poprawić ten projekt https://github.com/bombela/backward-cpp
i teraz działa i na mingw+clang , stacktrace wygląda tak:
image

0
Marius.Maximus napisał(a):

@GodOfCode.: dziekuje za materiały , sugestie i uwagi, widzę że powróciłeś z banicji

Przez przypadek trafiłem na ten projekt https://github.com/ssbssa/dwarfstack i tutaj to działa np.

wynik dzialania tego przykąłdu https://github.com/ssbssa/dwarfstack/blob/master/examples/location/location.c

base address: 0x00007FF6950B0000 (location.exe)
    stack 00: 0x00007FF6950B143D (obj2.c:61:3) [obj2func2]
    stack 01: 0x00007FF6950B1418 (obj2.c:66:3) [obj2func]
    stack 02: 0x00007FF6950B13A8 (location.c:14:3) [d]
    stack 03: 0x00007FF6950B13B8 (location.c:19:3) [c]
    stack 04: 0x00007FF6950B13C8 (location.c:24:3) [b]
    stack 05: 0x00007FF6950B13D8 (location.c:29:3) [a]
    stack 06: 0x00007FF6950B13FA (location.c:34:3) [main]
    stack 07: 0x00007FF6950B1314 (crtexe.c:267:15) [__tmainCRTStartup]
    stack 08: 0x00007FF6950B1365 (crtexe.c:188:9) [mainCRTStartup]

Pozostała z problemami:

  • C++23 <stacktrace> = choc mam clang 16.0.5 to na Windows jeszcze to nie dotarło, nie ma tego pliku
  • Boost stacktrace() = nie wyświetla ani nazw funkcji ani linii kodu na Windows
  • libbacktrace , działa podobnie jak boost, czyli ani nazw funkcji ani linii kodu na Windows, a w sumie boost uzywa tej biblioteki wiec i wynik nie dziwi
  • https://github.com/Febbe/stacktrace nazwy funkcji są zagmatwane przez manglowanie ale wyświetla poprawne linie kodu (brak demanglingu) , z nie działających działa najlepiej ;)

@Marius.Maximus: Co do tego że boost stacktrace i libbacktrace nie dziala na Windowsie to się nie zgodzę. Dziś to uruchomiłem na QT 5.3.1 z MinGW 4.8.2 i Boost 1.69.0

Niestety jest to trochę pokręcone bo do działania Boost::stacktrace potrzebuje libbacktrace do wyświetlania bardziej szczegółowych informacji na Windowsie. (Gdy używamy MinGW na msvc działa z marszu)

Więcej info na ten temat tu https://www.boost.org/doc/libs/1_69_0/doc/html/stacktrace/configuration_and_build.html#ftn.stacktrace.configuration_and_build.f0

Z powyższego linku dowiadujemy się że bibliotekę Libbacktrace można zbudować na MSYS. Ja użyłem MSYS2.

Skonfigurowałem ją tak by kompilator jakiego ma użyć podczas budowania pochodził z toolsów QT, i zbudowałem bibliotekę. Potem połączyłem to z boostem tak żeby wiedział gdzie ma headery do LIbbacktrace i zaczęło hulać

Moja konsola wygląda tak:

terminate called after throwing an instance of 'std::runtime_error'
what(): test
Crashed:
0# boost::stacktrace::basic_stacktrace<std::allocatorboost::stacktrace::frame >::init(unsigned int, unsigned int) at ../boost/boost/stacktrace/stacktrace.hpp:75
1# ala() at ../stc_mingw482/main.cpp:38
2# ma() at ../stc_mingw482/main.cpp:45
3# my_signal_handler(int) at ../stc_mingw482/main.cpp:51 <<<<<< Dotąd nas interesuje

4# _imp___set_invalid_parameter_handler in C:\Windows\System32\msvcrt.dll
5# _imp___set_invalid_parameter_handler in C:\Windows\System32\msvcrt.dll
6# _imp___set_invalid_parameter_handler in C:\Qt\Qt5.3.1\5.3\mingw482_32\bin\libstdc++-6.dll
7# main at ../stc_mingw482/main.cpp:66
8# __tmainCRTStartup in D:\Projekty\stc_mingw482_qt571\build-stc_mingw482-Desktop_Qt_5_3_MinGW_32bit-Debug\debug\stc_mingw482.exe
9# _imp___set_invalid_parameter_handler in C:\Windows\System32\KERNEL32.DLL
10# _imp___set_invalid_parameter_handler in C:\Windows\SYSTEM32\ntdll.dll
11# _imp___set_invalid_parameter_handler in C:\Windows\SYSTEM32\ntdll.dll

Wszystkie nazwy wyświetlają się prawidłowo.

Sprawdzę jeszcze nowsze wersje.

1 użytkowników online, w tym zalogowanych: 0, gości: 1