@@ -65,57 +65,47 @@ namespace detail {
6565 }
6666 #endif
6767 #ifdef CPPTRACE_HAS_DL_FIND_OBJECT
68- inline std::vector< object_frame> get_frames_object_info ( const std::vector< frame_ptr>& addrs ) {
68+ inline object_frame get_frame_object_info ( frame_ptr address ) {
6969 // Use _dl_find_object when we can, it's orders of magnitude faster
70- std::vector<object_frame> frames;
71- frames.reserve (addrs.size ());
72- for (const frame_ptr addr : addrs) {
73- object_frame frame;
74- frame.raw_address = addr;
75- frame.object_address = 0 ;
76- dl_find_object result;
77- if (_dl_find_object (reinterpret_cast <void *>(addr), &result) == 0 ) { // thread safe
78- if (result.dlfo_link_map ->l_name != nullptr && result.dlfo_link_map ->l_name [0 ] != 0 ) {
79- frame.object_path = result.dlfo_link_map ->l_name ;
70+ object_frame frame;
71+ frame.raw_address = address;
72+ frame.object_address = 0 ;
73+ dl_find_object result;
74+ if (_dl_find_object (reinterpret_cast <void *>(address), &result) == 0 ) { // thread safe
75+ if (result.dlfo_link_map ->l_name != nullptr && result.dlfo_link_map ->l_name [0 ] != 0 ) {
76+ frame.object_path = result.dlfo_link_map ->l_name ;
77+ } else {
78+ // empty l_name, this means it's the currently running executable
79+ // TODO: Caching and proper handling
80+ char buffer[CPPTRACE_PATH_MAX + 1 ]{};
81+ auto res = readlink (" /proc/self/exe" , buffer, CPPTRACE_PATH_MAX );
82+ if (res == -1 ) {
83+ // error handling?
8084 } else {
81- // empty l_name, this means it's the currently running executable
82- // TODO: Caching and proper handling
83- char buffer[CPPTRACE_PATH_MAX + 1 ]{};
84- auto res = readlink (" /proc/self/exe" , buffer, CPPTRACE_PATH_MAX );
85- if (res == -1 ) {
86- // error handling?
87- } else {
88- frame.object_path = buffer;
89- }
85+ frame.object_path = buffer;
9086 }
91- frame.object_address = addr
92- - to_frame_ptr (result.dlfo_link_map ->l_addr )
93- + get_module_image_base (frame.object_path );
9487 }
95- frames.push_back (frame);
88+ frame.object_address = address
89+ - to_frame_ptr (result.dlfo_link_map ->l_addr )
90+ + get_module_image_base (frame.object_path );
9691 }
97- return frames ;
92+ return frame ;
9893 }
9994 #else
100- // aladdr queries are needed to get pre-ASLR addresses and targets to run addr2line on
101- inline std::vector< object_frame> get_frames_object_info ( const std::vector< frame_ptr>& addrs ) {
95+ // dladdr queries are needed to get pre-ASLR addresses and targets to run addr2line on
96+ inline object_frame get_frame_object_info ( frame_ptr address ) {
10297 // reference: https://github.com/bminor/glibc/blob/master/debug/backtracesyms.c
103- std::vector<object_frame> frames;
104- frames.reserve (addrs.size ());
105- for (const frame_ptr addr : addrs) {
106- Dl_info info;
107- object_frame frame;
108- frame.raw_address = addr;
109- frame.object_address = 0 ;
110- if (dladdr (reinterpret_cast <void *>(addr), &info)) { // thread safe
111- frame.object_path = info.dli_fname ;
112- frame.object_address = addr
113- - reinterpret_cast <std::uintptr_t >(info.dli_fbase )
114- + get_module_image_base (info.dli_fname );
115- }
116- frames.push_back (frame);
98+ Dl_info info;
99+ object_frame frame;
100+ frame.raw_address = address;
101+ frame.object_address = 0 ;
102+ if (dladdr (reinterpret_cast <void *>(address), &info)) { // thread safe
103+ frame.object_path = info.dli_fname ;
104+ frame.object_address = address
105+ - reinterpret_cast <std::uintptr_t >(info.dli_fbase )
106+ + get_module_image_base (info.dli_fname );
117107 }
118- return frames ;
108+ return frame ;
119109 }
120110 #endif
121111 #else
@@ -156,34 +146,36 @@ namespace detail {
156146 }
157147 }
158148
159- // aladdr queries are needed to get pre-ASLR addresses and targets to run addr2line on
160- inline std::vector<object_frame> get_frames_object_info (const std::vector<frame_ptr>& addrs) {
161- // reference: https://github.com/bminor/glibc/blob/master/debug/backtracesyms.c
149+ inline object_frame get_frame_object_info (frame_ptr address) {
150+ object_frame frame;
151+ frame.raw_address = address;
152+ frame.object_address = 0 ;
153+ HMODULE handle;
154+ // Multithread safe as long as another thread doesn't come along and free the module
155+ if (GetModuleHandleExA (
156+ GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS ,
157+ reinterpret_cast <const char *>(address),
158+ &handle
159+ )) {
160+ frame.object_path = get_module_name (handle);
161+ frame.object_address = address
162+ - reinterpret_cast <std::uintptr_t >(handle)
163+ + get_module_image_base (frame.object_path );
164+ } else {
165+ std::fprintf (stderr, " %s\n " , std::system_error (GetLastError (), std::system_category ()).what ());
166+ }
167+ return frame;
168+ }
169+ #endif
170+
171+ inline std::vector<object_frame> get_frames_object_info (const std::vector<frame_ptr>& addresses) {
162172 std::vector<object_frame> frames;
163- frames.reserve (addrs.size ());
164- for (const frame_ptr addr : addrs) {
165- object_frame frame;
166- frame.raw_address = addr;
167- frame.object_address = 0 ;
168- HMODULE handle;
169- // Multithread safe as long as another thread doesn't come along and free the module
170- if (GetModuleHandleExA (
171- GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS ,
172- reinterpret_cast <const char *>(addr),
173- &handle
174- )) {
175- frame.object_path = get_module_name (handle);
176- frame.object_address = addr
177- - reinterpret_cast <std::uintptr_t >(handle)
178- + get_module_image_base (frame.object_path );
179- } else {
180- std::fprintf (stderr, " %s\n " , std::system_error (GetLastError (), std::system_category ()).what ());
181- }
182- frames.push_back (frame);
173+ frames.reserve (addresses.size ());
174+ for (const frame_ptr address : addresses) {
175+ frames.push_back (get_frame_object_info (address));
183176 }
184177 return frames;
185178 }
186- #endif
187179
188180 inline object_frame resolve_safe_object_frame (const safe_object_frame& frame) {
189181 return {
0 commit comments