Add cpptrace::can_get_safe_object_frame and add ctrace prefix for can_signal_safe_unwind
This commit is contained in:
parent
98ea78445c
commit
6877782d96
@ -774,6 +774,7 @@ namespace cpptrace {
|
|||||||
};
|
};
|
||||||
void get_safe_object_frame(frame_ptr address, safe_object_frame* out);
|
void get_safe_object_frame(frame_ptr address, safe_object_frame* out);
|
||||||
bool can_signal_safe_unwind();
|
bool can_signal_safe_unwind();
|
||||||
|
bool can_get_safe_object_frame();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -790,9 +791,9 @@ see the comprehensive overview and demo at [signal-safe-tracing.md](docs/signal-
|
|||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> Currently signal-safe stack unwinding is only possible with `libunwind`, which must be
|
> Currently signal-safe stack unwinding is only possible with `libunwind`, which must be
|
||||||
> [manually enabled](#library-back-ends). If signal-safe unwinding isn't supported, `safe_generate_raw_trace` will just
|
> [manually enabled](#library-back-ends). If signal-safe unwinding isn't supported, `safe_generate_raw_trace` will just
|
||||||
> produce an empty trace. `can_signal_safe_unwind` can be used to check for signal-safe unwinding support. If object
|
> produce an empty trace. `can_signal_safe_unwind` can be used to check for signal-safe unwinding support and
|
||||||
> information can't be resolved in a signal-safe way then `get_safe_object_frame` will not populate fields beyond the
|
> `can_get_safe_object_frame` can be used to check `get_safe_object_frame` support. If object information can't be
|
||||||
> `raw_address`.
|
> resolved in a signal-safe way then `get_safe_object_frame` will not populate fields beyond the `raw_address`.
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> `_dl_find_object` is required for signal-safe stack tracing. This is a relatively recent addition to glibc, added in
|
> `_dl_find_object` is required for signal-safe stack tracing. This is a relatively recent addition to glibc, added in
|
||||||
|
|||||||
@ -168,5 +168,6 @@ struct ctrace_safe_object_frame {
|
|||||||
};
|
};
|
||||||
size_t ctrace_safe_generate_raw_trace(ctrace_frame_ptr* buffer, size_t size, size_t skip, size_t max_depth);
|
size_t ctrace_safe_generate_raw_trace(ctrace_frame_ptr* buffer, size_t size, size_t skip, size_t max_depth);
|
||||||
void ctrace_get_safe_object_frame(ctrace_frame_ptr address, ctrace_safe_object_frame* out);
|
void ctrace_get_safe_object_frame(ctrace_frame_ptr address, ctrace_safe_object_frame* out);
|
||||||
ctrace_bool can_signal_safe_unwind();
|
ctrace_bool ctrace_can_signal_safe_unwind();
|
||||||
|
ctrace_bool ctrace_can_get_safe_object_frame();
|
||||||
```
|
```
|
||||||
|
|||||||
@ -73,6 +73,7 @@ namespace cpptrace {
|
|||||||
void get_safe_object_frame(frame_ptr address, safe_object_frame* out);
|
void get_safe_object_frame(frame_ptr address, safe_object_frame* out);
|
||||||
// signal-safe
|
// signal-safe
|
||||||
bool can_signal_safe_unwind();
|
bool can_signal_safe_unwind();
|
||||||
|
bool can_get_safe_object_frame();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -104,6 +105,9 @@ only ways to do this safely as far as I can tell.
|
|||||||
`safe_generate_raw_trace` will just produce an empty trace and if object information can't be resolved in a signal-safe
|
`safe_generate_raw_trace` will just produce an empty trace and if object information can't be resolved in a signal-safe
|
||||||
way then `get_safe_object_frame` will not populate fields beyond the `raw_address`.
|
way then `get_safe_object_frame` will not populate fields beyond the `raw_address`.
|
||||||
|
|
||||||
|
`cpptrace::can_signal_safe_unwind` and `cpptrace::can_get_safe_object_frame` can be used to check for safe tracing
|
||||||
|
support.
|
||||||
|
|
||||||
Currently the only back-end that can unwind safely is libunwind. Currently, the only way I know to get `dladdr`'s
|
Currently the only back-end that can unwind safely is libunwind. Currently, the only way I know to get `dladdr`'s
|
||||||
information in a signal-safe manner is `_dl_find_object`, which doesn't exist on macos (or windows of course). If anyone
|
information in a signal-safe manner is `_dl_find_object`, which doesn't exist on macos (or windows of course). If anyone
|
||||||
knows ways to do these safely on other platforms, I'd be much appreciative.
|
knows ways to do these safely on other platforms, I'd be much appreciative.
|
||||||
|
|||||||
@ -235,6 +235,7 @@ namespace cpptrace {
|
|||||||
// signal-safe
|
// signal-safe
|
||||||
CPPTRACE_EXPORT void get_safe_object_frame(frame_ptr address, safe_object_frame* out);
|
CPPTRACE_EXPORT void get_safe_object_frame(frame_ptr address, safe_object_frame* out);
|
||||||
CPPTRACE_EXPORT bool can_signal_safe_unwind();
|
CPPTRACE_EXPORT bool can_signal_safe_unwind();
|
||||||
|
CPPTRACE_EXPORT bool can_get_safe_object_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|||||||
@ -131,7 +131,8 @@ CTRACE_BEGIN_DEFINITIONS
|
|||||||
/* ctrace::safe: */
|
/* ctrace::safe: */
|
||||||
CPPTRACE_EXPORT size_t ctrace_safe_generate_raw_trace(ctrace_frame_ptr* buffer, size_t size, size_t skip, size_t max_depth);
|
CPPTRACE_EXPORT size_t ctrace_safe_generate_raw_trace(ctrace_frame_ptr* buffer, size_t size, size_t skip, size_t max_depth);
|
||||||
CPPTRACE_EXPORT void ctrace_get_safe_object_frame(ctrace_frame_ptr address, ctrace_safe_object_frame* out);
|
CPPTRACE_EXPORT void ctrace_get_safe_object_frame(ctrace_frame_ptr address, ctrace_safe_object_frame* out);
|
||||||
CPPTRACE_EXPORT ctrace_bool can_signal_safe_unwind(void);
|
CPPTRACE_EXPORT ctrace_bool ctrace_can_signal_safe_unwind(void);
|
||||||
|
CPPTRACE_EXPORT ctrace_bool ctrace_can_get_safe_object_frame(void);
|
||||||
|
|
||||||
/* ctrace::io: */
|
/* ctrace::io: */
|
||||||
CPPTRACE_EXPORT ctrace_owning_string ctrace_stacktrace_to_string(const ctrace_stacktrace* trace, ctrace_bool use_color);
|
CPPTRACE_EXPORT ctrace_owning_string ctrace_stacktrace_to_string(const ctrace_stacktrace* trace, ctrace_bool use_color);
|
||||||
|
|||||||
@ -53,6 +53,10 @@ namespace detail {
|
|||||||
// may return the object that defines the function descriptor (and not the object that contains the code
|
// may return the object that defines the function descriptor (and not the object that contains the code
|
||||||
// implementing the function), or fail to find any object at all.
|
// implementing the function), or fail to find any object at all.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_get_safe_object_frame() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -63,6 +67,10 @@ namespace detail {
|
|||||||
out->address_relative_to_object_start = 0;
|
out->address_relative_to_object_start = 0;
|
||||||
out->object_path[0] = 0;
|
out->object_path[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_get_safe_object_frame() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
namespace cpptrace {
|
namespace cpptrace {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
void get_safe_object_frame(frame_ptr address, safe_object_frame* out);
|
void get_safe_object_frame(frame_ptr address, safe_object_frame* out);
|
||||||
|
|
||||||
|
bool has_get_safe_object_frame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -333,4 +333,8 @@ namespace cpptrace {
|
|||||||
bool can_signal_safe_unwind() {
|
bool can_signal_safe_unwind() {
|
||||||
return detail::has_safe_unwind();
|
return detail::has_safe_unwind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool can_get_safe_object_frame() {
|
||||||
|
return detail::has_get_safe_object_frame();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -310,10 +310,14 @@ extern "C" {
|
|||||||
cpptrace::get_safe_object_frame(address, reinterpret_cast<cpptrace::safe_object_frame*>(out));
|
cpptrace::get_safe_object_frame(address, reinterpret_cast<cpptrace::safe_object_frame*>(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrace_bool can_signal_safe_unwind() {
|
ctrace_bool ctrace_can_signal_safe_unwind() {
|
||||||
return cpptrace::can_signal_safe_unwind();
|
return cpptrace::can_signal_safe_unwind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctrace_bool ctrace_can_get_safe_object_frame(void) {
|
||||||
|
return cpptrace::can_get_safe_object_frame();
|
||||||
|
}
|
||||||
|
|
||||||
// ctrace::io:
|
// ctrace::io:
|
||||||
ctrace_owning_string ctrace_stacktrace_to_string(const ctrace_stacktrace* trace, ctrace_bool use_color) {
|
ctrace_owning_string ctrace_stacktrace_to_string(const ctrace_stacktrace* trace, ctrace_bool use_color) {
|
||||||
if(!trace || !trace->frames) {
|
if(!trace || !trace->frames) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user