source: git/omalloc/omRet2Info.c

spielwiese
Last change on this file was 75f460, checked in by Hans Schoenemann <hannes@…>, 9 years ago
format
  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*******************************************************************
2 *  File:    omRetur2Info.c
3 *  Purpose: translation of return addr to RetInfo
4 *  Author:  obachman (Olaf Bachmann)
5 *  Created: 11/99
6 *******************************************************************/
7#include <stdio.h>
8#include <string.h>
9
10#ifndef PACKAGE
11#include "omConfig.h"
12#endif
13
14#ifndef OM_NDEBUG
15
16#include "omDerivedConfig.h"
17#include "omStructs.h"
18#include "omRet2Info.h"
19#include "omGetBackTrace.h"
20
21#ifndef MAXPATHLEN
22#define MAXPATHLEN 1024
23#endif
24
25/* define to also print return addresses in (default)
26   output of omPrintInfo */
27/* #define OM_PRINT_RETURN_ADDRESS */
28static char om_this_prog[MAXPATHLEN] = "";
29
30#ifndef OM_MAX_BACKTRACE_DEPTH
31#define OM_MAX_BACKTRACE_DEPTH 16
32#endif
33
34void omInitRet_2_Info(const char* argv0)
35{
36//  char buf[MAXPATHLEN];
37
38  if (argv0 != NULL) // // && omFindExec(argv0, buf))
39  {
40    strncpy(om_this_prog, argv0, MAXPATHLEN); // // buf);
41    om_this_prog[MAXPATHLEN - 1]= '\0';
42  }
43}
44
45
46int omBackTrace_2_RetInfo(void** bt, omRetInfo info, int max)
47{
48  int i=0, j=0, filled = 0;
49  if (max <= 0 || bt == NULL || info == NULL) return 0;
50  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
51  memset(info, 0, max*sizeof(omRetInfo_t));
52  while (i<max)
53  {
54    if (bt[i])
55    {
56      info[j].addr = bt[i];
57      j++;
58    }
59    i++;
60  }
61  if (j == 0) return 0;
62
63#if defined(HAVE_POPEN) && defined(OM_PROG_ADDR2LINE)
64  if (*om_this_prog != '\0')
65  {
66    char command[2*MAXPATHLEN + 15 + OM_MAX_BACKTRACE_DEPTH*(2*SIZEOF_VOIDP + 4)];
67    FILE *pipe;
68    int l;
69    l = sprintf(command, "%s -s -C -f -e %s",
70                OM_PROG_ADDR2LINE, om_this_prog);
71    i=0;
72    while (i<j)
73    {
74      l+=sprintf(&command[l], " %p", info[i].addr);
75      i++;
76    }
77    fflush(NULL);
78    pipe = popen(command, "r");
79    if (pipe != NULL)
80    {
81        /* An output entry of addr2line looks as follows:
82FunctionName
83File:Line
84        */
85      while ((filled < j) &&
86             (fscanf(pipe, "%200[^\n]\n%200[^:]:%d\n", info[filled].func, info[filled].file, &(info[filled].line)) == 3))
87      {
88        if (*info[filled].func != '?' && *info[filled].file != '?' && info[filled].line > 0)
89          filled++;
90      }
91      pclose(pipe);
92    }
93    return filled;
94  }
95#endif
96  return j;
97}
98
99int omPrintRetInfo(omRetInfo info, int max, FILE* fd, const char* fmt)
100{
101  int i = 0;
102  if (max <= 0 || info == NULL || fmt == NULL || fd == NULL) return 0;
103  while (i < max && info[i].addr != NULL)
104  {
105    int l = 0;
106    while (fmt[l] != 0)
107    {
108      if (fmt[l] == '%')
109      {
110        l++;
111        if (fmt[l] == 'p') fprintf(fd, "%p", info[i].addr);
112        else if (fmt[l] == 'f') fprintf(fd, "%-20s", (*info[i].file != '\0' ? info[i].file : "??"));
113        else if (fmt[l] == 'F') fprintf(fd, "%-20s", (*info[i].func != '\0' ? info[i].func : "??"));
114        else if (fmt[l] == 'l') fprintf(fd, "%d", info[i].line);
115        else if (fmt[l] == 'N')
116        {
117          if (*info[i].func != '\0')
118          {
119            char* found = (char*) strchr(info[i].func, '(');
120            if (found) *found = '\0';
121            fprintf(fd, "%-20s", info[i].func);
122            if (found) *found = '(';
123          }
124          else
125            fprintf(fd, "%-20s", "??");
126        }
127        else if (fmt[l] == 'L')
128        {
129          int n = fprintf(fd, "%s:%d", (*info[i].func != '\0' ? info[i].file : "??"), info[i].line);
130          if (n < 20) fprintf(fd, "%*s", 20-n, " ");
131        }
132        else if (fmt[l] == 'i') fprintf(fd, "%d", i);
133        else
134        {
135          fputc('%', fd);
136          l--;
137        }
138      }
139      else
140      {
141        fputc(fmt[l], fd);
142      }
143      l++;
144    }
145    i++;
146  }
147  return i;
148}
149
150int omPrintBackTrace(void** bt, int max, FILE* fd)
151{
152  int i;
153
154  omRetInfo_t info[OM_MAX_BACKTRACE_DEPTH];
155  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
156
157  i = omBackTrace_2_RetInfo(bt, info, max);
158#ifdef OM_PRINT_RETURN_ADDRESS
159  return omPrintRetInfo(info, i, fd, "  #%i at %L in %N ra=%p\n");
160#else
161  return omPrintRetInfo(info, i, fd, "  #%i at %L in %N\n");
162#endif
163}
164
165int omPrintCurrentBackTraceMax(FILE* fd, int max)
166{
167  int i;
168  void* bt[OM_MAX_BACKTRACE_DEPTH];
169  if (max > OM_MAX_BACKTRACE_DEPTH)
170    max = OM_MAX_BACKTRACE_DEPTH;
171  if (max <= 0) return 0;
172  i = omGetBackTrace(bt, 1, max);
173  return omPrintBackTrace(bt, i, fd);
174}
175
176/*************************************************************
177 *
178 * Various Filters
179 *
180 *************************************************************/
181int omFilterRetInfo_i(omRetInfo info, int max, int i)
182{
183  int j=0, k=i;
184
185  while (k < max)
186  {
187    info[j] = info[k];
188    j++;
189    k++;
190  }
191  return j;
192}
193
194/*************************************************************
195 *
196 * Low level routines
197 *
198 *************************************************************/
199
200int _omPrintBackTrace(void** bt, int max, FILE* fd , OM_FLR_DECL)
201{
202#ifndef __OPTIMIZE__
203  int i = 0;
204
205  omRetInfo_t info[OM_MAX_BACKTRACE_DEPTH];
206  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
207  if (bt != NULL)
208  {
209  for (; i<max; i++)
210  {
211    if (bt[i] == NULL)
212    {
213      max = i+1;
214      break;
215    }
216  }
217  i = omBackTrace_2_RetInfo(bt, info, max);
218  }
219#ifdef OM_TRACK_RETURN
220  if (i == 0)
221    i = omBackTrace_2_RetInfo(((void*)&r),info, 1);
222#endif
223#ifndef OM_INTERNAL_DEBUG
224  if (i > 1)
225  {
226#ifdef OM_TRACK_RETURN
227    if (r != NULL)
228      omFilterRetInfo(info, i, addr_i == r);
229#endif
230#ifdef OM_TRACK_FILE_LINE
231    if (f != NULL && l > 0)
232      omFilterRetInfo(info, i, strcmp(f, file_i) == 0 && l + 2 >= line_i && l - 2 <= line_i);
233#endif
234    /* if we have both, use overwrite what we got from return addressse --
235       they sometimes are wrong */
236#if defined(OM_TRACK_RETURN) && defined(OM_TRACK_FILE_LINE)
237    if (r != NULL && info[0].addr == r && l > 0 && f != 0)
238    {
239      strcpy(info[0].file, f);
240      info[0].line = l;
241    }
242#endif
243  }
244  if (i == 0)
245  {
246#endif /* ! OM_INTERNAL_DEBUG */
247
248#ifdef OM_TRACK_FILE_LINE
249    fprintf(fd, " %s:%d", f, l);
250#endif
251#ifdef OM_TRACK_RETURN
252    fprintf(fd," ra=%p", r);
253#endif
254
255#ifndef OM_INTERNAL_DEBUG
256    return 1;
257  }
258  else
259#endif /* ! OM_INTERNAL_DEBUG */
260#ifdef OM_PRINT_RETURN_ADDRESS
261    return omPrintRetInfo(info, i, fd, "\n  #%i at %L in %N ra=%p");
262#else
263    return omPrintRetInfo(info, i, fd, "\n  #%i at %L in %N");
264#endif
265#else
266  return 0;
267#endif
268}
269
270int _omPrintCurrentBackTrace(FILE* fd , OM_FLR_DECL)
271{
272#ifdef __OPTIMIZE__
273  /* does not work without -g */
274  return 0;
275#else
276  int i;
277  void* bt[OM_MAX_BACKTRACE_DEPTH];
278
279  i = omGetBackTrace(bt, 1, OM_MAX_BACKTRACE_DEPTH);
280  return _omPrintBackTrace(bt, i, fd , OM_FLR_VAL);
281#endif
282}
283#endif /* ! OM_NDEBUG */
Note: See TracBrowser for help on using the repository browser.