Various macos work (#7)
This commit is contained in:
parent
d955c61cd6
commit
8e4ee0783f
57
.github/workflows/build.yml
vendored
57
.github/workflows/build.yml
vendored
@ -44,6 +44,42 @@ jobs:
|
|||||||
-D${{matrix.demangle}}=On \
|
-D${{matrix.demangle}}=On \
|
||||||
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h
|
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h
|
||||||
make
|
make
|
||||||
|
build-macos:
|
||||||
|
runs-on: macos-13
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
compiler: [g++-13, clang++]
|
||||||
|
target: [Debug]
|
||||||
|
std: [11, 20]
|
||||||
|
unwind: [
|
||||||
|
CPPTRACE_UNWIND_WITH_EXECINFO,
|
||||||
|
CPPTRACE_UNWIND_WITH_NOTHING,
|
||||||
|
]
|
||||||
|
symbols: [
|
||||||
|
#CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE,
|
||||||
|
CPPTRACE_GET_SYMBOLS_WITH_LIBDL,
|
||||||
|
CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE,
|
||||||
|
CPPTRACE_GET_SYMBOLS_WITH_NOTHING,
|
||||||
|
]
|
||||||
|
demangle: [
|
||||||
|
CPPTRACE_DEMANGLE_WITH_CXXABI,
|
||||||
|
CPPTRACE_DEMANGLE_WITH_NOTHING,
|
||||||
|
]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
|
||||||
|
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
|
||||||
|
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||||
|
-D${{matrix.unwind}}=On \
|
||||||
|
-D${{matrix.symbols}}=On \
|
||||||
|
-D${{matrix.demangle}}=On
|
||||||
|
make
|
||||||
build-windows:
|
build-windows:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
strategy:
|
strategy:
|
||||||
@ -108,6 +144,27 @@ jobs:
|
|||||||
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \
|
-DCPPTRACE_BACKTRACE_PATH=/usr/lib/gcc/x86_64-linux-gnu/10/include/backtrace.h \
|
||||||
${{matrix.config}}
|
${{matrix.config}}
|
||||||
make
|
make
|
||||||
|
build-macos-full-or-auto:
|
||||||
|
runs-on: macos-13
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
compiler: [g++-13, clang++]
|
||||||
|
target: [Debug]
|
||||||
|
std: [11, 20]
|
||||||
|
config: [""]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
|
||||||
|
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
|
||||||
|
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||||
|
${{matrix.config}}
|
||||||
|
make
|
||||||
# TODO: -DCMAKE_CXX_STANDARD isn't being honored?
|
# TODO: -DCMAKE_CXX_STANDARD isn't being honored?
|
||||||
# build-linux-full-or-auto-23:
|
# build-linux-full-or-auto-23:
|
||||||
# runs-on: ubuntu-22.04
|
# runs-on: ubuntu-22.04
|
||||||
|
|||||||
70
.github/workflows/test.yml
vendored
70
.github/workflows/test.yml
vendored
@ -53,6 +53,49 @@ jobs:
|
|||||||
working-directory: build
|
working-directory: build
|
||||||
run: |
|
run: |
|
||||||
./test | python3 ../test/test.py "${{matrix.compiler}}" "${{matrix.unwind}}" "${{matrix.symbols}}" "${{matrix.demangle}}"
|
./test | python3 ../test/test.py "${{matrix.compiler}}" "${{matrix.unwind}}" "${{matrix.symbols}}" "${{matrix.demangle}}"
|
||||||
|
test-macos:
|
||||||
|
runs-on: macos-13
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
compiler: [g++-13, clang++]
|
||||||
|
target: [Debug]
|
||||||
|
std: [11, 20]
|
||||||
|
unwind: [
|
||||||
|
CPPTRACE_UNWIND_WITH_EXECINFO,
|
||||||
|
#CPPTRACE_UNWIND_WITH_NOTHING,
|
||||||
|
]
|
||||||
|
symbols: [
|
||||||
|
#CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE,
|
||||||
|
CPPTRACE_GET_SYMBOLS_WITH_LIBDL,
|
||||||
|
#CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE,
|
||||||
|
#CPPTRACE_GET_SYMBOLS_WITH_NOTHING,
|
||||||
|
]
|
||||||
|
demangle: [
|
||||||
|
CPPTRACE_DEMANGLE_WITH_CXXABI,
|
||||||
|
#CPPTRACE_DEMANGLE_WITH_NOTHING,
|
||||||
|
]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
|
||||||
|
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
|
||||||
|
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||||
|
-D${{matrix.unwind}}=On \
|
||||||
|
-D${{matrix.symbols}}=On \
|
||||||
|
-D${{matrix.demangle}}=On \
|
||||||
|
-DCPPTRACE_BUILD_TEST=On \
|
||||||
|
$(if [ "${{matrix.symbols}}" = "CPPTRACE_GET_SYMBOLS_WITH_LIBDL" ]; then echo "-DCPPTRACE_BUILD_TEST_RDYNAMIC=On"; else echo ""; fi) \
|
||||||
|
-DBUILD_SHARED_LIBS=On
|
||||||
|
make
|
||||||
|
- name: test
|
||||||
|
working-directory: build
|
||||||
|
run: |
|
||||||
|
./test | python3 ../test/test.py "${{matrix.compiler}}" "${{matrix.unwind}}" "${{matrix.symbols}}" "${{matrix.demangle}}"
|
||||||
test-windows:
|
test-windows:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
strategy:
|
strategy:
|
||||||
@ -130,6 +173,33 @@ jobs:
|
|||||||
working-directory: build
|
working-directory: build
|
||||||
run: |
|
run: |
|
||||||
./test | python3 ../test/test.py "${{matrix.compiler}}"
|
./test | python3 ../test/test.py "${{matrix.compiler}}"
|
||||||
|
test-macos-full-or-auto:
|
||||||
|
runs-on: macos-13
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
compiler: [g++-13, clang++]
|
||||||
|
target: [Debug]
|
||||||
|
std: [11, 20]
|
||||||
|
config: [""]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: build
|
||||||
|
run: |
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
cmake .. \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{matrix.target}} \
|
||||||
|
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
|
||||||
|
-DCMAKE_CXX_STANDARD=${{matrix.std}} \
|
||||||
|
${{matrix.config}} \
|
||||||
|
-DCPPTRACE_BUILD_TEST=On \
|
||||||
|
-DBUILD_SHARED_LIBS=On
|
||||||
|
make
|
||||||
|
- name: test
|
||||||
|
working-directory: build
|
||||||
|
run: |
|
||||||
|
./test | python3 ../test/test.py "${{matrix.compiler}}"
|
||||||
test-windows-full-or-auto:
|
test-windows-full-or-auto:
|
||||||
runs-on: windows-2019
|
runs-on: windows-2019
|
||||||
strategy:
|
strategy:
|
||||||
|
|||||||
30
README.md
30
README.md
@ -54,33 +54,33 @@ also manually set which back-end you want used.
|
|||||||
**Unwinding**
|
**Unwinding**
|
||||||
|
|
||||||
| Library | CMake config | Windows | Linux | macOS | Info |
|
| Library | CMake config | Windows | Linux | macOS | Info |
|
||||||
|------------|---------------------------------|---------|-------|-------|--------------------------------------------------------------------|
|
| ---------- | ------------------------------- | ------- | ----- | ----- | ------------------------------------------------------------------ |
|
||||||
| execinfo.h | `CPPTRACE_UNWIND_WITH_EXECINFO` | ❌ | ✔️ | ✔️ | Frames are captured with `execinfo.h`'s `backtrace`, part of libc. |
|
| execinfo.h | `CPPTRACE_UNWIND_WITH_EXECINFO` | ❌ | ✔️ | ✔️ | Frames are captured with `execinfo.h`'s `backtrace`, part of libc. |
|
||||||
| winapi | `CPPTRACE_UNWIND_WITH_WINAPI` | ✔️ | ❌ | ❌ | Frames are captured with `CaptureStackBackTrace`. |
|
| winapi | `CPPTRACE_UNWIND_WITH_WINAPI` | ✔️ | ❌ | ❌ | Frames are captured with `CaptureStackBackTrace`. |
|
||||||
| N/A | `CPPTRACE_UNWIND_WITH_NOTHING` | ✔️ | ✔️ | ✔️ | Unwinding is not done, stack traces will be empty. |
|
| N/A | `CPPTRACE_UNWIND_WITH_NOTHING` | ✔️ | ✔️ | ✔️ | Unwinding is not done, stack traces will be empty. |
|
||||||
|
|
||||||
These back-ends require a fixed buffer has to be created to read addresses into while unwinding. By default the buffer
|
These back-ends require a fixed buffer has to be created to read addresses into while unwinding. By default the buffer
|
||||||
can hold addresses for 100 frames (beyond the `skip` frames). This is configurable with `CPPTRACE_HARD_MAX_FRAMES`.
|
can hold addresses for 100 frames (beyond the `skip` frames). This is configurable with `CPPTRACE_HARD_MAX_FRAMES`.
|
||||||
|
|
||||||
**Symbol resolution**
|
**Symbol resolution**
|
||||||
|
|
||||||
| Library | CMake config | Windows | Linux | macOS | Info |
|
| Library | CMake config | Windows | Linux | macOS | Info |
|
||||||
|--------------|------------------------------------------|---------|-------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
| ------------ | ---------------------------------------- | ------- | ----- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| libbacktrace | `CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE` | ❌ | ✔️ | ❌ | Libbacktrace is already installed on most systems, or available through the compiler directly. If it is installed but backtrace.h is not already in the include path (this can happen when using clang when backtrace lives in gcc's include folder), `CPPTRACE_BACKTRACE_PATH` can be used to specify where the library should be looked for. |
|
| libbacktrace | `CPPTRACE_GET_SYMBOLS_WITH_LIBBACKTRACE` | ❌ | ✔️ | ❌ | Libbacktrace is already installed on most systems, or available through the compiler directly. If it is installed but backtrace.h is not already in the include path (this can happen when using clang when backtrace lives in gcc's include folder), `CPPTRACE_BACKTRACE_PATH` can be used to specify where the library should be looked for. |
|
||||||
| libdl | `CPPTRACE_GET_SYMBOLS_WITH_LIBDL` | ❌ | ✔️ | ✔️ | Libdl uses dynamic export information. Compiling with `-rdynamic` is needed for symbol information to be retrievable. |
|
| libdl | `CPPTRACE_GET_SYMBOLS_WITH_LIBDL` | ❌ | ✔️ | ✔️ | Libdl uses dynamic export information. Compiling with `-rdynamic` is needed for symbol information to be retrievable. |
|
||||||
| addr2line | `CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE` | ❌ | ✔️ | ❌ | Symbols are resolved by invoking `addr2line` via `fork()`. |
|
| addr2line | `CPPTRACE_GET_SYMBOLS_WITH_ADDR2LINE` | ❌ | ✔️ | ❌ (TODO) | Symbols are resolved by invoking `addr2line` via `fork()`. |
|
||||||
| dbghelp | `CPPTRACE_GET_SYMBOLS_WITH_DBGHELP` | ✔️ | ❌ | ❌ | Dbghelp.h allows access to symbols via debug info. |
|
| dbghelp | `CPPTRACE_GET_SYMBOLS_WITH_DBGHELP` | ✔️ | ❌ | ❌ | Dbghelp.h allows access to symbols via debug info. |
|
||||||
| N/A | `CPPTRACE_GET_SYMBOLS_WITH_NOTHING` | ✔️ | ✔️ | ✔️ | No attempt is made to resolve symbols. |
|
| N/A | `CPPTRACE_GET_SYMBOLS_WITH_NOTHING` | ✔️ | ✔️ | ✔️ | No attempt is made to resolve symbols. |
|
||||||
|
|
||||||
**Demangling**
|
**Demangling**
|
||||||
|
|
||||||
Lastly, depending on other back-ends used a demangler back-end may be needed. A demangler back-end is not needed when
|
Lastly, depending on other back-ends used a demangler back-end may be needed. A demangler back-end is not needed when
|
||||||
doing full traces with libbacktrace, getting symbols with addr2line, or getting symbols with dbghelp.
|
doing full traces with libbacktrace, getting symbols with addr2line, or getting symbols with dbghelp.
|
||||||
|
|
||||||
| Library | CMake config | Windows | Linux | Info |
|
| Library | CMake config | Windows | Linux | Info |
|
||||||
|---------|--------------|---------|-------|------|
|
| -------- | -------------------------------- | ------- | ----- | ---------------------------------------------------------------------------------- |
|
||||||
| cxxabi.h | `CPPTRACE_DEMANGLE_WITH_CXXABI` | | | Should be available everywhere other than [msvc](https://godbolt.org/z/93ca9rcdz). |
|
| cxxabi.h | `CPPTRACE_DEMANGLE_WITH_CXXABI` | | | Should be available everywhere other than [msvc](https://godbolt.org/z/93ca9rcdz). |
|
||||||
| N/A | `CPPTRACE_DEMANGLE_WITH_NOTHING` | | | Don't attempt to do anything beyond what the symbol resolution back-end does. |
|
| N/A | `CPPTRACE_DEMANGLE_WITH_NOTHING` | | | Don't attempt to do anything beyond what the symbol resolution back-end does. |
|
||||||
|
|
||||||
**Full tracing**
|
**Full tracing**
|
||||||
|
|
||||||
|
|||||||
@ -102,6 +102,9 @@ constexpr const char* const ws = " \t\n\r\f\v";
|
|||||||
|
|
||||||
CPPTRACE_MAYBE_UNUSED
|
CPPTRACE_MAYBE_UNUSED
|
||||||
static std::string trim(const std::string& s) {
|
static std::string trim(const std::string& s) {
|
||||||
|
if(s == "") {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
size_t l = s.find_first_not_of(ws);
|
size_t l = s.find_first_not_of(ws);
|
||||||
size_t r = s.find_last_not_of(ws) + 1;
|
size_t r = s.find_last_not_of(ws) + 1;
|
||||||
return s.substr(l, r - l);
|
return s.substr(l, r - l);
|
||||||
|
|||||||
@ -22,6 +22,7 @@ namespace cpptrace {
|
|||||||
|
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <mach-o/dyld.h>
|
#include <mach-o/dyld.h>
|
||||||
#include <sys/syslimits.h>
|
#include <sys/syslimits.h>
|
||||||
|
|
||||||
|
|||||||
@ -136,16 +136,27 @@ namespace cpptrace {
|
|||||||
auto output = split(trim(resolve_addresses(address_input, object_name)), "\n");
|
auto output = split(trim(resolve_addresses(address_input, object_name)), "\n");
|
||||||
internal_verify(output.size() == entries_vec.size());
|
internal_verify(output.size() == entries_vec.size());
|
||||||
for(size_t i = 0; i < output.size(); i++) {
|
for(size_t i = 0; i < output.size(); i++) {
|
||||||
// result will be of the form <identifier> " at " path:line
|
// Result will be of the form <identifier> " at " path:line
|
||||||
// path may be ?? if addr2line cannot resolve, line may be ?
|
// The path may be ?? if addr2line cannot resolve, line may be ?
|
||||||
|
// Edge cases:
|
||||||
|
// ?? ??:0
|
||||||
const auto& line = output[i];
|
const auto& line = output[i];
|
||||||
auto at_location = line.find(" at ");
|
std::size_t at_location = line.find(" at ");
|
||||||
internal_verify(at_location != std::string::npos);
|
std::size_t symbol_end;
|
||||||
auto symbol = line.substr(0, at_location);
|
std::size_t filename_start;
|
||||||
|
if(at_location != std::string::npos) {
|
||||||
|
symbol_end = at_location;
|
||||||
|
filename_start = at_location + 4;
|
||||||
|
} else {
|
||||||
|
internal_verify(line.find("?? ") == 0, "Unexpected edge case while processing addr2line output");
|
||||||
|
symbol_end = 2;
|
||||||
|
filename_start = 3;
|
||||||
|
}
|
||||||
|
auto symbol = line.substr(0, symbol_end);
|
||||||
auto colon = line.rfind(":");
|
auto colon = line.rfind(":");
|
||||||
internal_verify(colon != std::string::npos);
|
internal_verify(colon != std::string::npos);
|
||||||
internal_verify(colon > at_location);
|
internal_verify(colon > filename_start);
|
||||||
auto filename = line.substr(at_location + 4, colon - at_location - 4);
|
auto filename = line.substr(filename_start, colon - filename_start);
|
||||||
auto line_number = line.substr(colon + 1);
|
auto line_number = line.substr(colon + 1);
|
||||||
if(line_number != "?") {
|
if(line_number != "?") {
|
||||||
entries_vec[i].second.get().line = std::stoi(line_number);
|
entries_vec[i].second.get().line = std::stoi(line_number);
|
||||||
|
|||||||
25
test/expected/macos.txt
Normal file
25
test/expected/macos.txt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
build/test||0||trace()
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||foo(int)
|
||||||
|
build/test||0||void foo<int>(int, int)
|
||||||
|
build/test||0||void foo<int, int>(int, int, int)
|
||||||
|
build/test||0||void foo<int, int, int>(int, int, int, int)
|
||||||
|
build/test||0||void foo<int, int, int, int>(int, int, int, int, int)
|
||||||
|
build/test||0||void foo<int, int, int, int, int>(int, int, int, int, int, int)
|
||||||
|
build/test||0||void foo<int, int, int, int, int, int>(int, int, int, int, int, int, int)
|
||||||
|
build/test||0||void foo<int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int)
|
||||||
|
build/test||0||void foo<int, int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int, int)
|
||||||
|
build/test||0||void foo<int, int, int, int, int, int, int, int, int>(int, int, int, int, int, int, int, int, int, int)
|
||||||
|
build/test||0||function_two(int, float)
|
||||||
|
build/test||0||function_one(int)
|
||||||
|
build/test||0||main
|
||||||
|
/usr/lib/dyld||0||start
|
||||||
@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
std::string normalize_filename(std::string name) {
|
std::string normalize_filename(std::string name) {
|
||||||
if(name.find('/') == 0 || (name.find(':') == 1 && std::isupper(name[0]))) {
|
if(name.find('/') == 0 || (name.find(':') == 1 && std::isupper(name[0]))) {
|
||||||
auto p = std::min(name.rfind("test/"), name.rfind("test\\"));
|
// build/test if the file is really an object name resolved by libdl
|
||||||
|
auto p = std::min({name.rfind("test/"), name.rfind("test\\"), name.rfind("build/test")});
|
||||||
return p == std::string::npos ? name : name.substr(p);
|
return p == std::string::npos ? name : name.substr(p);
|
||||||
} else {
|
} else {
|
||||||
return name;
|
return name;
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import platform
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
MAX_LINE_DIFF = 2
|
MAX_LINE_DIFF = 2
|
||||||
@ -28,8 +29,10 @@ def main():
|
|||||||
elif sys.argv[1].startswith("cl"):
|
elif sys.argv[1].startswith("cl"):
|
||||||
target.append("msvc")
|
target.append("msvc")
|
||||||
|
|
||||||
if os.name == "nt":
|
if platform.system() == "Windows":
|
||||||
target.append("windows")
|
target.append("windows")
|
||||||
|
elif platform.system() == "Darwin":
|
||||||
|
target.append("macos")
|
||||||
else:
|
else:
|
||||||
target.append("linux")
|
target.append("linux")
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user