d715a5b192a9e7ab3a2765371f2f668dd0c08fd8
[scilab.git] / scilab / modules / core / src / cpp / backtrace_print.cpp
1 /*
2 Copyright (C) 2006  EDF - Code Saturne
3 Copyright (C) 2001 - DIGITEO - Sylvestre LEDRU. Adapted for Scilab
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20 #include <cstring>
21 #include <cstdio>
22 #include <sstream>
23 #include <string>
24
25 extern "C" {
26 #include "backtrace.h"
27 #include "backtrace_print.h"
28 #include "localization.h"
29 #include "os_string.h"
30 }
31
32 #ifdef _MSC_VER
33 #define snprintf _snprintf
34 #endif
35
36 #define FUNCNAMEBUFFERSIZE 256
37 #define BTBUFFERSIZE 1024
38
39 const char * backtrace_print(int niv_debut, int unmangle)
40 {
41     size_t ind = 0;
42     sci_backtrace_t * tr = 0;
43     std::stringstream ss;
44
45     tr = sci_backtrace_create();
46
47     if (tr)
48     {
49         char s_func_buf[FUNCNAMEBUFFERSIZE + 3];
50         const char * s_file = NULL;
51         const char * s_func = NULL;
52         const char * s_addr = NULL;
53         const char s_unknown[] = "?";
54         const char s_empty[] = "";
55         const char * s_prefix = s_empty;
56         char buffer[BTBUFFERSIZE];
57
58         if (unmangle)
59         {
60             sci_backtrace_demangle(tr);
61         }
62
63         size_t nbr = sci_backtrace_size(tr);
64
65         if (nbr > 0)
66         {
67             ss << _("\nCall stack:\n");
68         }
69
70         for (ind = niv_debut; ind < nbr; ind++)
71         {
72             s_file = sci_backtrace_file(tr, (int)ind);
73             s_func = sci_backtrace_function(tr, (int)ind);
74             s_addr = sci_backtrace_address(tr, (int)ind);
75
76             if (!s_file)
77             {
78                 s_file = s_unknown;
79             }
80
81             if (!s_func)
82             {
83                 strcpy(s_func_buf, "?");
84             }
85             else
86             {
87                 s_func_buf[0] = '<';
88                 strncpy(s_func_buf + 1, s_func, FUNCNAMEBUFFERSIZE);
89                 s_func_buf[FUNCNAMEBUFFERSIZE] = '\0';
90                 strcat(s_func_buf, ">");
91             }
92
93             if (!s_addr)
94             {
95                 s_addr = s_unknown;
96             }
97
98             snprintf(buffer, BTBUFFERSIZE, "%s%4lu: %-8s %-32s (%s)", s_prefix, ind - niv_debut + 1, s_addr, s_func_buf, s_file);
99             ss << buffer << std::endl;
100         }
101
102         sci_backtrace_destroy(tr);
103
104         if (nbr > 0)
105         {
106             ss << _("End of stack\n\n");
107         }
108     }
109
110     return os_strdup(ss.str().c_str());
111 }