Comments (5)
The erroneous output is from using g++-10, -std=c++11, and ubuntu-22.04
from libbacktrace.
libbacktrace works by looking up a PC value in the address ranges recorded by functions. The mere presence of the function name in the info section doesn't tell us much. What matters is the associated address ranges, and whether the PC values found on the stack are in those ranges.
Is there a way that I can reproduce the problem?
from libbacktrace.
Hi, thanks so much for the reply. I have my implementation at
https://github.com/jeremy-rifkin/cpptrace/blob/4dac00a87f749752ca4a042c55806e71550da2e0/src/full/full_trace_with_libbacktrace.cpp
and the test program at
https://github.com/jeremy-rifkin/cpptrace/blob/4dac00a87f749752ca4a042c55806e71550da2e0/test/test.cpp
It might be possible to reproduce with the following:
git clone https://github.com/jeremy-rifkin/cpptrace.git
git checkout 4dac00a
mkdir build
cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_COMPILER=g++-10 \
-DCMAKE_CXX_STANDARD=11 \
-DCPPTRACE_FULL_TRACE_WITH_LIBBACKTRACE=On \
-DCPPTRACE_BUILD_TEST=On
make
./test
As an update, I was able to get at least the symbol names by falling back to backtrace_syminfo
https://github.com/jeremy-rifkin/cpptrace/blob/4dac00a87f749752ca4a042c55806e71550da2e0/src/symbols/symbols_with_libbacktrace.cpp#L59-L73 (this is a slightly different back-end that takes addresses from execinfo.h rather than backtrace_full
).
Is there a reason why the file/line information would not be retrievable but the symbol would be?
from libbacktrace.
I have constructed a better reproducible example that reproduces locally for me:
repro_lib.cpp
#include <iostream>
#include <vector>
#include <string>
#include <cstddef>
#include <linux/limits.h>
#include <unistd.h>
#include <backtrace.h>
struct stacktrace_frame {
uintptr_t address;
int line;
int col;
std::string filename;
std::string symbol;
};
struct trace_data {
std::vector<stacktrace_frame>& frames;
size_t& skip;
};
int full_callback(void* data_pointer, uintptr_t address, const char* file, int line, const char* symbol) {
trace_data& data = *reinterpret_cast<trace_data*>(data_pointer);
if(data.skip > 0) {
data.skip--;
} else {
data.frames.push_back({
address,
line,
-1,
file ? file : "",
symbol ? symbol : ""
});
}
return 0;
}
void syminfo_callback(void* data, uintptr_t, const char* symbol, uintptr_t, uintptr_t) {
stacktrace_frame& frame = *static_cast<stacktrace_frame*>(data);
frame.symbol = symbol ? symbol : "";
}
void error_callback(void*, const char*, int) {
// nothing for now
}
backtrace_state* get_backtrace_state() {
// backtrace_create_state must be called only one time per program
static backtrace_state* state = nullptr;
static bool called = false;
if(!called) {
state = backtrace_create_state(nullptr, true, error_callback, nullptr);
called = true;
}
return state;
}
std::vector<stacktrace_frame> generate_trace(size_t skip) {
std::vector<stacktrace_frame> frames;
skip++; // add one for this call
trace_data data { frames, skip };
backtrace_full(get_backtrace_state(), 0, full_callback, error_callback, &data);
for(auto& frame : frames) {
if(frame.symbol.empty()) {
// fallback, try to at least recover the symbol name with backtrace_syminfo
backtrace_syminfo(
get_backtrace_state(),
reinterpret_cast<uintptr_t>(frame.address),
syminfo_callback,
error_callback,
&frame
);
}
}
return frames;
}
repro.cpp
#include <iostream>
#include <vector>
#include <string>
#include <cstddef>
struct stacktrace_frame {
uintptr_t address;
int line;
int col;
std::string filename;
std::string symbol;
};
std::vector<stacktrace_frame> generate_trace(size_t skip);
void trace() {
for(const auto& frame : generate_trace(0)) {
std::cout
<< frame.filename
<< "||"
<< frame.line
<< "||"
<< frame.symbol
<< std::endl;
}
}
void foo(int n) {
if(n == 0) {
trace();
} else {
foo(n - 1);
}
}
template<typename... Args>
void foo(int x, Args... args) {
foo(args...);
}
void function_two(int, float) {
foo(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
}
void function_one(int) {
function_two(0, 0);
}
int main() {
function_one(0);
}
/usr/bin/c++ -g -std=c++14 -fPIC -Wall -Wextra -Werror=return-type -Wshadow -o repro_lib.o -c repro_lib.cpp
/usr/bin/ar qc librepro_lib.a repro_lib.o
/usr/bin/ranlib librepro_lib.a
/usr/bin/c++ -g -fPIE -o repro.o -c repro.cpp
/usr/bin/c++ -g repro.o -o repro librepro_lib.a -lbacktrace
It is an issue with static linking it seems. Doing it as a shared library works.
/usr/bin/c++ -g -std=c++14 -fPIC -Wall -Wextra -Werror=return-type -Wshadow -o repro_lib.o -c repro_lib.cpp
/usr/bin/c++ -fPIC -g -shared -Wl,-soname,repro_lib.so -o repro_lib.so repro_lib.o -lbacktrace
/usr/bin/c++ -g -fPIE -o repro.o -c repro.cpp
/usr/bin/c++ -g repro.o -o repro -Wl,-rpath,. repro_lib.so
from libbacktrace.
It looks like I'm running into the same issues when I have an executable -> a.so -> b.so (which then invokes libbacktrace).
from libbacktrace.
Related Issues (20)
- No backtrace with Mingw64 and clang++ HOT 4
- MUSL CRuntime used by Alpine Linux HOT 5
- Build Issue MacOS
- libbacktrace does not include the origin library in its description.
- Libbacktrace issue with mingw HOT 4
- Libbacktrace fails to resolve symbols, if debug/symbol information resides (only) in a seperate file HOT 9
- Libbacktrace doesn't work on Linux ARM-32 bits HOT 2
- Can't get information in main() HOT 4
- Is it safe to load two executables? HOT 1
- mismatch with glibc backtrace HOT 5
- mtest_minidebug test failed HOT 6
- how can I build and install it? HOT 1
- Unlike GDB, LLVM ORC generated functions are not resolved HOT 1
- please add hints to error message "no debug info in Mach-O executable" HOT 5
- Test suite failures on macOS 12 HOT 4
- Trailing whitespace HOT 1
- dSYM files are not found for applications/packages HOT 1
- Building using Git-Bash fails HOT 1
- Stack overflow in `elf_add` if debug info found by build id contains MiniDebugInfo HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from libbacktrace.