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/* A stack unwinder. */ 18501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 19501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifndef _CORKSCREW_BACKTRACE_H 20501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#define _CORKSCREW_BACKTRACE_H 21501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 22501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifdef __cplusplus 23501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownextern "C" { 24501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif 25501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 26501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <sys/types.h> 27501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/ptrace.h> 28501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/map_info.h> 29501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#include <corkscrew/symbol_table.h> 30501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 31501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 32501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Describes a single frame of a backtrace. 33501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 34501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Browntypedef struct { 35501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown uintptr_t absolute_pc; /* absolute PC offset */ 36501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown uintptr_t stack_top; /* top of stack for this frame */ 37501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t stack_size; /* size of this stack frame */ 38501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} backtrace_frame_t; 39501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 40501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 41501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Describes the symbols associated with a backtrace frame. 42501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 43501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Browntypedef struct { 4419b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown uintptr_t relative_pc; /* relative frame PC offset from the start of the library, 45501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown or the absolute PC if the library is unknown */ 4619b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown uintptr_t relative_symbol_addr; /* relative offset of the symbol from the start of the 4719b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown library or 0 if the library is unknown */ 48f0c5872637a63e28e3cd314cfc915c07f76df9c6Jeff Brown char* map_name; /* executable or library name, or NULL if unknown */ 4919b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown char* symbol_name; /* symbol name, or NULL if unknown */ 50501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown char* demangled_name; /* demangled symbol name, or NULL if unknown */ 51501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} backtrace_symbol_t; 52501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 53501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 54501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Unwinds the call stack for the current thread of execution. 55501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Populates the backtrace array with the program counters from the call stack. 56501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Returns the number of frames collected, or -1 if an error occurred. 57501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 58501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownssize_t unwind_backtrace(backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth); 59501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 60501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 61501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Unwinds the call stack for a thread within this process. 62501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Populates the backtrace array with the program counters from the call stack. 63501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Returns the number of frames collected, or -1 if an error occurred. 64501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * 65501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * The task is briefly suspended while the backtrace is being collected. 66501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 67501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t* backtrace, 68501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown size_t ignore_depth, size_t max_depth); 69501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 70501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 71501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Unwinds the call stack of a task within a remote process using ptrace(). 72501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Populates the backtrace array with the program counters from the call stack. 73501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Returns the number of frames collected, or -1 if an error occurred. 74501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 75501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownssize_t unwind_backtrace_ptrace(pid_t tid, const ptrace_context_t* context, 76501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth); 77501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 78501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 79501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Gets the symbols for each frame of a backtrace. 80501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * The symbols array must be big enough to hold one symbol record per frame. 81501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * The symbols must later be freed using free_backtrace_symbols. 82501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 83501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid get_backtrace_symbols(const backtrace_frame_t* backtrace, size_t frames, 84501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_symbol_t* backtrace_symbols); 85501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 86501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 87501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Gets the symbols for each frame of a backtrace from a remote process. 88501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * The symbols array must be big enough to hold one symbol record per frame. 89501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * The symbols must later be freed using free_backtrace_symbols. 90501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 91501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid get_backtrace_symbols_ptrace(const ptrace_context_t* context, 92501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown const backtrace_frame_t* backtrace, size_t frames, 93501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown backtrace_symbol_t* backtrace_symbols); 94501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 95501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown/* 96501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown * Frees the storage associated with backtrace symbols. 97501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown */ 98501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brownvoid free_backtrace_symbols(backtrace_symbol_t* backtrace_symbols, size_t frames); 99501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 10019b39f371be5250e7b9e88016be1e5e665367b3fJeff Brownenum { 10119b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown // A hint for how big to make the line buffer for format_backtrace_line 10219b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown MAX_BACKTRACE_LINE_LENGTH = 800, 10319b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown}; 10419b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown 10519b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown/** 10619b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown * Formats a line from a backtrace as a zero-terminated string into the specified buffer. 10719b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown */ 10819b39f371be5250e7b9e88016be1e5e665367b3fJeff Brownvoid format_backtrace_line(unsigned frameNumber, const backtrace_frame_t* frame, 10919b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown const backtrace_symbol_t* symbol, char* buffer, size_t bufferSize); 11019b39f371be5250e7b9e88016be1e5e665367b3fJeff Brown 111501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#ifdef __cplusplus 112501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown} 113501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif 114501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown 115501edd29b823ce1301d2effdd3a9e4b6e2b20b76Jeff Brown#endif // _CORKSCREW_BACKTRACE_H 116