summaryrefslogtreecommitdiffstats
path: root/recipes-devtools/clang/clang/0024-libunwind-Added-unw_backtrace-method.patch
blob: 9d6f74fa4c86bb062a9bfd769d7cd356806e3b2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
From b75d3ed8f09ee013809a4321ff21b3bfb7e4a467 Mon Sep 17 00:00:00 2001
From: Maksim Kita <maksim-kita@yandex-team.ru>
Date: Sun, 23 May 2021 10:27:29 +0000
Subject: [PATCH] libunwind: Added unw_backtrace method

Source: https://github.com/ClickHouse-Extras/libunwind/commit/52f0f7861926cbfaef7e6c97d8a6d7ba2a1f6747#diff-a82fc885e2e4facf4b92d26171c13aa4aa5db296f77e1158ba2f8664e3bd1f5c
Upstream-Status: Pending
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 libunwind/include/libunwind.h |  1 +
 libunwind/src/libunwind.cpp   | 18 ++++++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index d2ad5ab87122..d735d955aee2 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -130,6 +130,7 @@ extern int unw_is_fpreg(unw_cursor_t *, unw_regnum_t) LIBUNWIND_AVAIL;
 extern int unw_is_signal_frame(unw_cursor_t *) LIBUNWIND_AVAIL;
 extern int unw_get_proc_name(unw_cursor_t *, char *, size_t, unw_word_t *) LIBUNWIND_AVAIL;
 //extern int       unw_get_save_loc(unw_cursor_t*, int, unw_save_loc_t*);
+extern int unw_backtrace(void **, int) LIBUNWIND_AVAIL;
 
 extern unw_addr_space_t unw_local_addr_space;
 
diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp
index 0faea2b78570..14bf07d8f470 100644
--- a/libunwind/src/libunwind.cpp
+++ b/libunwind/src/libunwind.cpp
@@ -349,7 +349,25 @@ void __unw_remove_dynamic_eh_frame_section(unw_word_t eh_frame_start) {
 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
 #endif // !defined(__USING_SJLJ_EXCEPTIONS__)
 
+int unw_backtrace(void **buffer, int size) {
+  unw_context_t context;
+  unw_cursor_t cursor;
+  if (unw_getcontext(&context) || unw_init_local(&cursor, &context)) {
+    return 0;
+  }
+
+  unw_word_t ip;
+  int current = 0;
+  while (unw_step(&cursor) > 0) {
+    if (current >= size || unw_get_reg(&cursor, UNW_REG_IP, &ip)) {
+      break;
+    }
 
+    buffer[current++] = reinterpret_cast<void *>(static_cast<uintptr_t>(ip));
+  }
+
+  return current;
+}
 
 // Add logging hooks in Debug builds only
 #ifndef NDEBUG