summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory LEOCADIE <gregory.leocadie@datadoghq.com>2022-09-21 21:25:31 +0200
committerDave Watson <dade.watson@gmail.com>2023-01-11 08:56:12 -0800
commit4fdee8080912fe6dd76e98526457125e9ee8ec03 (patch)
tree091bf806fb79e9a3b1a9fd880f3202765d64f806
parent3adec79a2a8be71ed384096dda7f00b143cc47f7 (diff)
downloadlibunwind-4fdee8080912fe6dd76e98526457125e9ee8ec03.tar.gz
Add unw_backtrace2 implementation
-rw-r--r--include/libunwind-common.h.in1
-rw-r--r--src/mi/backtrace.c33
2 files changed, 31 insertions, 3 deletions
diff --git a/include/libunwind-common.h.in b/include/libunwind-common.h.in
index 9d62aa91..3f04a1c4 100644
--- a/include/libunwind-common.h.in
+++ b/include/libunwind-common.h.in
@@ -316,5 +316,6 @@ extern int unw_get_proc_name_by_ip (unw_addr_space_t, unw_word_t, char *,
size_t, unw_word_t *, void *);
extern const char *unw_strerror (int);
extern int unw_backtrace (void **, int);
+extern int unw_backtrace2 (void **, int, unw_context_t*);
extern unw_addr_space_t unw_local_addr_space;
diff --git a/src/mi/backtrace.c b/src/mi/backtrace.c
index b2815137..b6c7457f 100644
--- a/src/mi/backtrace.c
+++ b/src/mi/backtrace.c
@@ -33,15 +33,16 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/* See glibc manual for a description of this function. */
static ALWAYS_INLINE int
-slow_backtrace (void **buffer, int size, unw_context_t *uc)
+slow_backtrace (void **buffer, int size, unw_context_t *uc, int flag)
{
unw_cursor_t cursor;
unw_word_t ip;
int n = 0;
- if (unlikely (unw_init_local (&cursor, uc) < 0))
+ if (unlikely (unw_init_local2 (&cursor, uc, flag) < 0))
return 0;
+
while (unw_step (&cursor) > 0)
{
if (n >= size)
@@ -69,7 +70,33 @@ unw_backtrace (void **buffer, int size)
if (unlikely (tdep_trace (&cursor, buffer, &n) < 0))
{
unw_getcontext (&uc);
- return slow_backtrace (buffer, size, &uc);
+ return slow_backtrace (buffer, size, &uc, 0);
+ }
+
+ return n;
+}
+
+int
+unw_backtrace2 (void **buffer, int size, unw_context_t* uc2)
+{
+ if (size == 0)
+ return 0;
+
+ if (uc2 == NULL)
+ return unw_backtrace(buffer, size);
+
+ unw_cursor_t cursor;
+ // need to copy, because the context will be modified by tdep_trace
+ unw_context_t uc = *(unw_context_t*)uc2;
+
+ if (unlikely (unw_init_local2 (&cursor, &uc, UNW_INIT_SIGNAL_FRAME) < 0))
+ return 0;
+
+ int n = size;
+
+ if (unlikely (tdep_trace (&cursor, buffer, &n) < 0))
+ {
+ return slow_backtrace (buffer, n, &uc, UNW_INIT_SIGNAL_FRAME);
}
return n;