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