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