Код: Выделить всё
g++ -g -O0 -fPIC -c ./doit.cpp -o doit.o
ar rv libdoit.a doit.o
g++ -g -O0 main.cpp -L. -Wl,--whole-archive -ldoit -Wl,--no-whole-archive -o static
rm libdoit.a
./static
g++ -shared -o libdoit.so doit.o
g++ -g -O0 main.cpp -L. -ldoit -o dynamic -Wl,-rpath=.
./dynamic
Код: Выделить всё
+ g++ -g -O0 -fPIC -c ./doit.cpp -o doit.o
+ ar rv libdoit.a doit.o
ar: creating libdoit.a
a - doit.o
+ g++ -g -O0 main.cpp -L. -Wl,--whole-archive -ldoit -Wl,--no-whole-archive -o static
+ rm libdoit.a
+ ./static
========== Stack Trace ==========
#0 0x55bb788ea1b2 + 0x0 (./static)
#1 0x55bb788ea1be + 0x0 (./static)
#2 0x55bb788ea1a2 + 0x0 (./static)
#3 0x7f074891224a + 0x0 (/lib/x86_64-linux-gnu/libc.so.6)
#4 0x7f0748912305 __libc_start_main + 0x85 (/lib/x86_64-linux-gnu/libc.so.6)
#5 0x55bb788ea0d1 + 0x0 (./static)
====================================
+ g++ -shared -o libdoit.so doit.o
+ g++ -g -O0 main.cpp -L. -ldoit -o dynamic -Wl,-rpath=.
+ ./dynamic
========== Stack Trace ==========
#0 0x7f86d2324182 + 0x0 (./libdoit.so)
#1 0x7f86d232418e doit() + 0x9 (./libdoit.so)
#2 0x55afae550142 + 0x0 (./dynamic)
#3 0x7f86d216124a + 0x0 (/lib/x86_64-linux-gnu/libc.so.6)
#4 0x7f86d2161305 __libc_start_main + 0x85 (/lib/x86_64-linux-gnu/libc.so.6)
#5 0x55afae550071 + 0x0 (./dynamic)
====================================
- Почему статически связанный исполняемый файл не отображает детали трассировки стека изнутри архива? Сначала я подумал, что это связано с тем, что для связывания исполняемого файла на самом деле не нужен символ Internal_doit(), поэтому он удаляется. Однако добавление -Wl,--whole-archive не устранило проблему.
- Почему динамически связанный исполняемый файл не отображает детали трассировки стека для кадра Internal_doit()? Код создан с использованием -O0, поэтому оптимизаций быть не должно.
- main.cpp
Код: Выделить всё
#include "doit.h" int main() { doit(); return 0; } - doit.h
Код: Выделить всё
#pragma once void doit(); - doit.cpp
Код: Выделить всё
#include "doit.h" #include #include #include #include #include // __cxa_demangle #include // dladdr #include // backtrace, backtrace_symbols inline void PrintCurrentThreadStack() { const int maxFrames = 64; const int framesToSkip = 0; void* addrs[512]; int captured = backtrace(addrs, maxFrames); std::printf("========== Stack Trace ==========\n"); for (int i = 0; i < captured; ++i) { if (i < (framesToSkip + 1)) continue; void* addr = addrs[i]; Dl_info info; std::memset(&info, 0, sizeof(info)); const char* moduleName = ""; const char* symName = ""; const void* symAddr = nullptr; if (dladdr(addr, &info)) { if (info.dli_fname) moduleName = info.dli_fname; if (info.dli_sname) symName = info.dli_sname; symAddr = info.dli_saddr; } int status = 0; char* demangled = abi::__cxa_demangle(symName, nullptr, nullptr, &status); const char* prettyName = (status == 0 && demangled) ? demangled : symName; std::uintptr_t off = 0; if (symAddr) { off = reinterpret_cast(addr) - reinterpret_cast(symAddr); } std::printf("#%-2d %p %s + 0x%zx (%s)\n", i - (framesToSkip + 1), addr, prettyName ? prettyName : "", off, moduleName ? moduleName : ""); if (demangled) std::free(demangled); } std::printf("====================================\n"); } static void internal_doit() { PrintCurrentThreadStack(); } void doit() { internal_doit(); }
Подробнее здесь: https://stackoverflow.com/questions/798 ... vs-dynamic