backtrace.c revision 501edd29b823ce1301d2effdd3a9e4b6e2b20b76
1501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 2501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Copyright (C) 2011 The Android Open Source Project 3501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * 4501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * you may not use this file except in compliance with the License. 6501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * You may obtain a copy of the License at 7501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * 8501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * 10501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Unless required by applicable law or agreed to in writing, software 11501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * See the License for the specific language governing permissions and 14501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * limitations under the License. 15501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 16501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 17501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#define LOG_TAG "Corkscrew" 18501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown//#define LOG_NDEBUG 0 19501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 20501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include "backtrace-arch.h" 21501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include "backtrace-helper.h" 22501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include "ptrace-arch.h" 23501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/map_info.h> 24501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/symbol_table.h> 25501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/ptrace.h> 26501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/demangle.h> 27501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 28501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <unistd.h> 29501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <signal.h> 30501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <pthread.h> 31501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <unwind.h> 32501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <sys/exec_elf.h> 33501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <cutils/log.h> 34501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 35501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#if HAVE_DLADDR 36501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <dlfcn.h> 37501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif 38501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 39501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Browntypedef struct { 40501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_frame_t* backtrace; 41501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t ignore_depth; 42501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t max_depth; 43501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t ignored_frames; 44501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t returned_frames; 45501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} backtrace_state_t; 46501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 47501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownstatic _Unwind_Reason_Code unwind_backtrace_callback(struct _Unwind_Context* context, void* arg) { 48501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_state_t* state = (backtrace_state_t*)arg; 49501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown uintptr_t pc = _Unwind_GetIP(context); 50501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (pc) { 51501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown // TODO: Get information about the stack layout from the _Unwind_Context. 52501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown // This will require a new architecture-specific function to query 53501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown // the appropriate registers. Current callers of unwind_backtrace 54501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown // don't need this information, so we won't bother collecting it just yet. 55501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown add_backtrace_entry(pc, state->backtrace, 56501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown state->ignore_depth, state->max_depth, 57501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown &state->ignored_frames, &state->returned_frames); 58501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 59501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown return state->returned_frames < state->max_depth ? _URC_NO_REASON : _URC_END_OF_STACK; 60501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 61501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 62501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownssize_t unwind_backtrace(backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) { 63501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_state_t state; 64501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown state.backtrace = backtrace; 65501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown state.ignore_depth = ignore_depth; 66501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown state.max_depth = max_depth; 67501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown state.ignored_frames = 0; 68501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown state.returned_frames = 0; 69501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 70501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown _Unwind_Reason_Code rc =_Unwind_Backtrace(unwind_backtrace_callback, &state); 71501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (state.returned_frames) { 72501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown return state.returned_frames; 73501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 74501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown return rc == _URC_END_OF_STACK ? 0 : -1; 75501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 76501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 77501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifdef CORKSCREW_HAVE_ARCH 78501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownstatic pthread_mutex_t g_unwind_signal_mutex = PTHREAD_MUTEX_INITIALIZER; 79501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownstatic volatile struct { 80501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_frame_t* backtrace; 81501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t ignore_depth; 82501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t max_depth; 83501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t returned_frames; 84501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown bool done; 85501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} g_unwind_signal_state; 86501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 87501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownstatic void unwind_backtrace_thread_signal_handler(int n, siginfo_t* siginfo, void* sigcontext) { 88501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_frame_t* backtrace = g_unwind_signal_state.backtrace; 89501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (backtrace) { 90501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.backtrace = NULL; 91501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.returned_frames = unwind_backtrace_signal_arch( 92501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown siginfo, sigcontext, backtrace, 93501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.ignore_depth, 94501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.max_depth); 95501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.done = true; 96501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 97501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 98501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif 99501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 100501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t* backtrace, 101501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t ignore_depth, size_t max_depth) { 102501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifdef CORKSCREW_HAVE_ARCH 103501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown struct sigaction act; 104501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown struct sigaction oact; 105501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown memset(&act, 0, sizeof(act)); 106501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown act.sa_sigaction = unwind_backtrace_thread_signal_handler; 107501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown act.sa_flags = SA_RESTART | SA_SIGINFO; 108501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown sigemptyset(&act.sa_mask); 109501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 110501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown pthread_mutex_lock(&g_unwind_signal_mutex); 111501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 112501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.backtrace = backtrace; 113501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.ignore_depth = ignore_depth; 114501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.max_depth = max_depth; 115501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.returned_frames = 0; 116501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.done = false; 117501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 118501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown ssize_t frames = -1; 119501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (!sigaction(SIGURG, &act, &oact)) { 120501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (!kill(tid, SIGURG)) { 121501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown while (!g_unwind_signal_state.done) { 122501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown usleep(1000); 123501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 124501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown frames = g_unwind_signal_state.returned_frames; 125501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 126501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown sigaction(SIGURG, &oact, NULL); 127501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 128501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 129501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown g_unwind_signal_state.backtrace = NULL; 130501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 131501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown pthread_mutex_unlock(&g_unwind_signal_mutex); 132501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown return frames; 133501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#else 134501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown return -1; 135501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif 136501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 137501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 138501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownssize_t unwind_backtrace_ptrace(pid_t tid, const ptrace_context_t* context, 139501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) { 140501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifdef CORKSCREW_HAVE_ARCH 141501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown return unwind_backtrace_ptrace_arch(tid, context, backtrace, ignore_depth, max_depth); 142501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#else 143501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown return -1; 144501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif 145501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 146501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 147501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownstatic void init_backtrace_symbol(backtrace_symbol_t* symbol, uintptr_t pc) { 148501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->relative_pc = pc; 149501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->map_info = NULL; 150501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->name = NULL; 151501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->demangled_name = NULL; 152501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 153501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 154501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid get_backtrace_symbols(const backtrace_frame_t* backtrace, size_t frames, 155501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_symbol_t* backtrace_symbols) { 156501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown const map_info_t* milist = my_map_info_list(); 157501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown for (size_t i = 0; i < frames; i++) { 158501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown const backtrace_frame_t* frame = &backtrace[i]; 159501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_symbol_t* symbol = &backtrace_symbols[i]; 160501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown init_backtrace_symbol(symbol, frame->absolute_pc); 161501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 162501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown const map_info_t* mi = find_map_info(milist, frame->absolute_pc); 163501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (mi) { 164501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->relative_pc = frame->absolute_pc - mi->start; 165501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->map_info = mi; 166501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#if HAVE_DLADDR 167501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown Dl_info info; 168501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (dladdr((const void*)frame->absolute_pc, &info) && info.dli_sname) { 169501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->name = info.dli_sname; 170501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->demangled_name = demangle_symbol_name(symbol->name); 171501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 172501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif 173501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 174501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 175501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 176501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 177501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid get_backtrace_symbols_ptrace(const ptrace_context_t* context, 178501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown const backtrace_frame_t* backtrace, size_t frames, 179501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_symbol_t* backtrace_symbols) { 180501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown for (size_t i = 0; i < frames; i++) { 181501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown const backtrace_frame_t* frame = &backtrace[i]; 182501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_symbol_t* symbol = &backtrace_symbols[i]; 183501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown init_backtrace_symbol(symbol, frame->absolute_pc); 184501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 185501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown const map_info_t* mi; 186501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown const symbol_t* s; 187501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown find_symbol_ptrace(context, frame->absolute_pc, &mi, &s); 188501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (mi) { 189501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->relative_pc = frame->absolute_pc - mi->start; 190501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->map_info = mi; 191501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 192501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown if (s) { 193501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->name = s->name; 194501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown symbol->demangled_name = demangle_symbol_name(symbol->name); 195501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 196501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 197501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 198501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 199501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid free_backtrace_symbols(backtrace_symbol_t* backtrace_symbols, size_t frames) { 200501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown for (size_t i = 0; i < frames; i++) { 201501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_symbol_t* symbol = &backtrace_symbols[i]; 202501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown free(symbol->demangled_name); 203501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown init_backtrace_symbol(symbol, 0); 204501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown } 205501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 206