source: git/omalloc/omRet2Info.c @ 8b4e34a

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