1 module tango.core.tools.FrameInfo;
2 
3 version (D_Version2):
4 
5 package:
6 
7 struct FrameInfo
8 {
9     /// line number in the source of the most likely start adress (0 if not available)
10     long line;
11     /// number of the stack frame (starting at 0 for the top frame)
12     size_t iframe;
13     /// offset from baseSymb: within the function, or from the closest symbol
14     ptrdiff_t offsetSymb;
15     /// adress of the symbol in this execution
16     size_t baseSymb;
17     /// offset within the image (from this you can use better methods to get line number
18     /// a posteriory)
19     ptrdiff_t offsetImg;
20     /// base adress of the image (will be dependent on randomization schemes)
21     size_t baseImg;
22     /// adress of the function, or at which the ipc will return
23     /// (which most likely is the one after the adress where it started)
24     /// this is the raw adress returned by the backtracing function
25     size_t address;
26     /// file (image) of the current adress
27     const(char)[] file;
28     /// name of the function, if possible demangled
29     char[] func;
30     /// extra information (for example calling arguments)
31     const(char)[] extra;
32     /// if the address is exact or it is the return address
33     bool exactAddress;
34     /// if this function is an internal functions (for example the backtracing function itself)
35     /// if true by default the frame is not printed
36     bool internalFunction;
37     alias void function(FrameInfo*,void delegate(in char[])) FramePrintHandler;
38     /// the default printing function
39     static FramePrintHandler defaultFramePrintingFunction;
40     /// writes out the current frame info
41     void writeOut(void delegate(in char[])sink){
42 
43         if (defaultFramePrintingFunction){
44             defaultFramePrintingFunction(&this,sink);
45         } else {
46             char[26] buf;
47             //auto len=snprintf(buf.ptr,26,"[%8zx]",address);
48             //sink(buf[0..len]);
49             //len=snprintf(buf.ptr,26,"%8zx",baseImg);
50             //sink(buf[0..len]);
51             //len=snprintf(buf.ptr,26,"%+td ",offsetImg);
52             //sink(buf[0..len]);
53             //while (++len<6) sink(" ");
54             if (func.length) {
55                 sink(func);
56             } else {
57                 sink("???");
58             }
59             for (size_t i=func.length;i<80;++i) sink(" ");
60             //len=snprintf(buf.ptr,26," @%zx",baseSymb);
61             //sink(buf[0..len]);
62             //len=snprintf(buf.ptr,26,"%+td ",offsetSymb);
63             //sink(buf[0..len]);
64             if (extra.length){
65                 sink(extra);
66                 sink(" ");
67             }
68             sink(file);
69             sink(":");
70             sink(ulongToUtf8(buf, line));
71         }
72     }
73     /// clears the frame information stored
74     void clear()
75     {
76         line=0;
77         iframe=-1;
78         offsetImg=0;
79         baseImg=0;
80         offsetSymb=0;
81         baseSymb=0;
82         address=0;
83         exactAddress=true;
84         internalFunction=false;
85         file=null;
86         func=null;
87         extra=null;
88     }
89 }
90 
91 const(char)[] ulongToUtf8 (char[] tmp, ulong val)
92 in {
93      assert (tmp.length > 19, "atoi buffer should be more than 19 chars wide");
94      }
95 body
96 {
97         char* p = tmp.ptr + tmp.length;
98 
99         do {
100              *--p = cast(char)((val % 10) + '0');
101              } while (val /= 10);
102 
103         return tmp [cast(size_t)(p - tmp.ptr) .. $];
104 }