1275970Scy/*
2275970Scy * Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
3275970Scy *
4275970Scy * Permission to use, copy, modify, and/or distribute this software for any
5275970Scy * purpose with or without fee is hereby granted, provided that the above
6275970Scy * copyright notice and this permission notice appear in all copies.
7275970Scy *
8275970Scy * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9275970Scy * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10275970Scy * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11275970Scy * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12275970Scy * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13275970Scy * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14275970Scy * PERFORMANCE OF THIS SOFTWARE.
15275970Scy */
16275970Scy
17275970Scy/* $Id: backtrace.h,v 1.2 2009/09/01 18:40:25 jinmei Exp $ */
18275970Scy
19275970Scy/*! \file isc/backtrace.h
20275970Scy * \brief provide a back trace of the running process to help debug problems.
21275970Scy *
22275970Scy * This module tries to get a back trace of the process using some platform
23275970Scy * dependent way when available.  It also manages an internal symbol table
24275970Scy * that maps function addresses used in the process to their textual symbols.
25275970Scy * This module is expected to be used to help debug when some fatal error
26275970Scy * happens.
27275970Scy *
28275970Scy * IMPORTANT NOTE: since the (major) intended use case of this module is
29275970Scy * dumping a back trace on a fatal error, normally followed by self termination,
30275970Scy * functions defined in this module generally doesn't employ assertion checks
31275970Scy * (if it did, a program bug could cause infinite recursive calls to a
32275970Scy * backtrace function).  These functions still perform minimal checks and return
33275970Scy * ISC_R_FAILURE if they detect an error, but the caller should therefore be
34275970Scy * very careful about the use of these functions, and generally discouraged to
35275970Scy * use them except in an exit path.  The exception is
36275970Scy * isc_backtrace_getsymbolfromindex(), which is expected to be used in a
37275970Scy * non-error-handling context and validates arguments with assertion checks.
38275970Scy */
39275970Scy
40275970Scy#ifndef ISC_BACKTRACE_H
41275970Scy#define ISC_BACKTRACE_H 1
42275970Scy
43275970Scy/***
44275970Scy ***	Imports
45275970Scy ***/
46275970Scy
47275970Scy#include <isc/types.h>
48275970Scy
49275970Scy/***
50275970Scy *** Types
51275970Scy ***/
52275970Scystruct isc_backtrace_symmap {
53275970Scy	void		*addr;
54275970Scy	const char	*symbol;
55275970Scy};
56275970Scy
57275970Scyextern const int isc__backtrace_nsymbols;
58275970Scyextern const isc_backtrace_symmap_t isc__backtrace_symtable[];
59275970Scy
60275970Scy/***
61275970Scy *** Functions
62275970Scy ***/
63275970Scy
64275970ScyISC_LANG_BEGINDECLS
65275970Scyisc_result_t
66275970Scyisc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes);
67275970Scy/*%<
68275970Scy * Get a back trace of the running process above this function itself.  On
69275970Scy * success, addrs[i] will store the address of the call point of the i-th
70275970Scy * stack frame (addrs[0] is the caller of this function).  *nframes will store
71275970Scy * the total number of frames.
72275970Scy *
73275970Scy * Requires (note that these are not ensured by assertion checks, see above):
74275970Scy *
75275970Scy *\li	'addrs' is a valid array containing at least 'maxaddrs' void * entries.
76275970Scy *
77275970Scy *\li	'nframes' must be non NULL.
78275970Scy *
79275970Scy * Returns:
80275970Scy *
81275970Scy *\li	#ISC_R_SUCCESS
82275970Scy *\li	#ISC_R_FAILURE
83275970Scy *\li	#ISC_R_NOTFOUND
84275970Scy *\li	#ISC_R_NOTIMPLEMENTED
85275970Scy */
86275970Scy
87275970Scyisc_result_t
88280849Scyisc_backtrace_getsymbolfromindex(int idx, const void **addrp,
89275970Scy				 const char **symbolp);
90275970Scy/*%<
91275970Scy * Returns the content of the internal symbol table of the given index.
92275970Scy * On success, *addrsp and *symbolp point to the address and the symbol of
93280849Scy * the 'index'th entry of the table, respectively.  If 'idx' is not in the
94275970Scy * range of the symbol table, ISC_R_RANGE will be returned.
95275970Scy *
96275970Scy * Requires
97275970Scy *
98275970Scy *\li	'addrp' must be non NULL && '*addrp' == NULL.
99275970Scy *
100275970Scy *\li	'symbolp' must be non NULL && '*symbolp' == NULL.
101275970Scy *
102275970Scy * Returns:
103275970Scy *
104275970Scy *\li	#ISC_R_SUCCESS
105275970Scy *\li	#ISC_R_RANGE
106275970Scy */
107275970Scy
108275970Scyisc_result_t
109275970Scyisc_backtrace_getsymbol(const void *addr, const char **symbolp,
110275970Scy			unsigned long *offsetp);
111275970Scy/*%<
112275970Scy * Searches the internal symbol table for the symbol that most matches the
113275970Scy * given 'addr'.  On success, '*symbolp' will point to the name of function
114275970Scy * to which the address 'addr' belong, and '*offsetp' will store the offset
115275970Scy * from the function's entry address to 'addr'.
116275970Scy *
117275970Scy * Requires (note that these are not ensured by assertion checks, see above):
118275970Scy *
119275970Scy *\li	'symbolp' must be non NULL && '*symbolp' == NULL.
120275970Scy *
121275970Scy *\li	'offsetp' must be non NULL.
122275970Scy *
123275970Scy * Returns:
124275970Scy *
125275970Scy *\li	#ISC_R_SUCCESS
126275970Scy *\li	#ISC_R_FAILURE
127275970Scy *\li	#ISC_R_NOTFOUND
128275970Scy */
129275970ScyISC_LANG_ENDDECLS
130275970Scy
131275970Scy#endif	/* ISC_BACKTRACE_H */
132