6a3b95e46287bec824d9ab0bda897d9e6d0016f0
[ghc.git] / includes / rts / Libdw.h
1 /* ---------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 2014-2015
4 *
5 * Producing DWARF-based stacktraces with libdw.
6 *
7 * --------------------------------------------------------------------------*/
8
9 #include "Rts.h"
10
11 #ifndef RTS_LIBDW_H
12 #define RTS_LIBDW_H
13
14 // Chunk capacity
15 // This is rather arbitrary
16 #define BACKTRACE_CHUNK_SZ 256
17
18 /*
19 * Note [Chunked stack representation]
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 *
22 * Consider the stack,
23 * main calls (bottom of stack)
24 * func1 which in turn calls
25 * func2 which calls
26 * func3 which calls
27 * func4 which calls
28 * func5 which calls
29 * func6 which calls
30 * func7 which requests a backtrace (top of stack)
31 *
32 * This would produce the Backtrace (using a smaller chunk size of three for
33 * illustrative purposes),
34 *
35 * Backtrace /----> Chunk /----> Chunk /----> Chunk
36 * last --------/ next --------/ next --------/ next
37 * n_frames=8 n_frames=2 n_frames=3 n_frames=3
38 * ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~
39 * func1 func4 func7
40 * main func3 func6
41 * func2 func5
42 *
43 */
44
45 /* A chunk of code addresses from an execution stack
46 *
47 * The first address in this list corresponds to the stack frame
48 * nearest to the "top" of the stack.
49 */
50 typedef struct BacktraceChunk_ {
51 StgWord n_frames; // number of frames in this chunk
52 struct BacktraceChunk_ *next; // the chunk following this one
53 StgPtr frames[BACKTRACE_CHUNK_SZ]; // the code addresses from the
54 // frames
55 } __attribute__((packed)) BacktraceChunk;
56
57 /* A chunked list of code addresses from an execution stack
58 *
59 * This structure is optimized for append operations since we append O(stack
60 * depth) times yet typically only traverse the stack trace once. Consequently,
61 * the "top" stack frame (that is, the one where we started unwinding) can be
62 * found in the last chunk. Yes, this is a bit inconsistent with the ordering
63 * within a chunk. See Note [Chunked stack representation] for a depiction.
64 */
65 typedef struct Backtrace_ {
66 StgWord n_frames; // Total number of frames in the backtrace
67 BacktraceChunk *last; // The first chunk of frames (corresponding to the
68 // bottom of the stack)
69 } Backtrace;
70
71 /* Various information describing the location of an address */
72 typedef struct Location_ {
73 const char *object_file;
74 const char *function;
75
76 // lineno and colno are only valid if source_file /= NULL
77 const char *source_file;
78 StgWord32 lineno;
79 StgWord32 colno;
80 } __attribute__((packed)) Location;
81
82 struct LibdwSession_;
83 typedef struct LibdwSession_ LibdwSession;
84
85 /* Free a backtrace */
86 void backtraceFree(Backtrace *bt);
87
88 /* Request a backtrace of the current stack state.
89 * May return NULL if a backtrace can't be acquired. */
90 Backtrace *libdwGetBacktrace(LibdwSession *session);
91
92 /* Lookup Location information for the given address.
93 * Returns 0 if successful, 1 if address could not be found. */
94 int libdwLookupLocation(LibdwSession *session, Location *loc, StgPtr pc);
95
96 #endif /* RTS_LIBDW_H */