source: git/omalloc/omRet2Info.c @ 91c4012

fieker-DuValspielwiese
Last change on this file since 91c4012 was b98efa, checked in by Olaf Bachmann <obachman@…>, 24 years ago
added addr2line test git-svn-id: file:///usr/local/Singular/svn/trunk@4533 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.7 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 *  Version: $Id: omRet2Info.c,v 1.4 2000-08-16 12:06:11 obachman Exp $
7 *******************************************************************/
8#include <stdio.h>
9#include <strings.h>
10
11#ifdef HAVE_CONFIG_H
12#include "omConfig.h"
13#endif
14
15#ifndef OM_NDEBUG
16
17#include "omDerivedConfig.h"
18#include "omStructs.h"
19#include "omRet2Info.h"
20#include "omFindExec.h"
21#include "omGetBackTrace.h"
22
23#ifndef MAXPATHLEN
24#define MAXPATHLEN 1024
25#endif
26
27static char om_this_prog[MAXPATHLEN] = "";
28
29#ifndef OM_MAX_BACKTRACE_DEPTH
30#define OM_MAX_BACKTRACE_DEPTH 16
31#endif
32
33void omInitRet_2_Info(const char* argv0)
34{
35  char buf[MAXPATHLEN];
36
37  if (argv0 != NULL && omFindExec(argv0, buf))
38  {
39    strcpy(om_this_prog, buf);
40  }
41}
42
43int omBackTrace_2_RetInfo(void** bt, omRetInfo info, int max)
44{
45  int i=0, j=0, filled = 0;
46  if (max <= 0 || bt == NULL || info == NULL) return 0;
47  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
48  memset(info, 0, max*sizeof(omRetInfo_t));
49  while (i<max)
50  {
51    if (bt[i])
52    {
53      info[j].addr = bt[i];
54      j++;
55    }
56    i++;
57  }
58  if (j == 0) return 0;
59 
60#if defined(HAVE_POPEN) && defined(OM_PROG_ADDR2LINE)
61  if (*om_this_prog != '\0')
62  {
63    char command[2*MAXPATHLEN + 15 + OM_MAX_BACKTRACE_DEPTH*(2*SIZEOF_VOIDP + 4)];
64    FILE *pipe;
65    int l;
66    l = sprintf(command, "%s -s -C -f -e %s", 
67                OM_PROG_ADDR2LINE, om_this_prog);
68    i=0;
69    while (i<j)
70    {
71      l+=sprintf(&command[l], " %p", info[i].addr);
72      i++;
73    }
74    pipe = popen(command, "r");
75    if (pipe != NULL)
76    {
77        /* An output entry of addr2line looks as follows:
78FunctionName
79File:Line
80        */
81      while ((filled < j) && 
82             (fscanf(pipe, "%100[^\n]\n%100[^:]:%d\n", info[filled].func, info[filled].file, &(info[filled].line)) == 3))
83      {
84        if (*info[filled].func != '?' && *info[filled].file != '?' && info[filled].line > 0)
85          filled++;
86      }
87      pclose(pipe);
88    }
89  }
90#endif 
91  return filled;
92}
93
94int omPrintRetInfo(omRetInfo info, int max, FILE* fd, const char* fmt)
95{
96  int i = 0;
97  if (max <= 0 || info == NULL || fmt == NULL || fd == NULL) return 0;
98  while (i < max && info[i].addr != NULL)
99  {
100    int l = 0;
101    while (fmt[l] != 0)
102    {
103      if (fmt[l] == '%')
104      {
105        l++;
106        if (fmt[l] == 'p') fprintf(fd, "%p", info[i].addr);
107        else if (fmt[l] == 'f') fprintf(fd, "%-20s", (*info[i].file != '\0' ? info[i].file : "??"));
108        else if (fmt[l] == 'F') fprintf(fd, "%-20s", (*info[i].func != '\0' ? info[i].func : "??"));
109        else if (fmt[l] == 'l') fprintf(fd, "%d", info[i].line);
110        else if (fmt[l] == 'L') 
111        {
112          int n = fprintf(fd, "%s:%d", (*info[i].func != '\0' ? info[i].file : "??"), info[i].line);
113          if (n < 20) fprintf(fd, "%*s", 20-n, " ");
114        }
115        else if (fmt[l] == 'i') fprintf(fd, "%d", i);
116        else
117        {
118          fputc('%', fd);
119          l--;
120        }
121      }
122      else
123      {
124        fputc(fmt[l], fd);
125      }
126      l++;
127    }
128    i++;
129  }
130  return i;
131}
132
133int omPrintBackTrace(void** bt, int max, FILE* fd)
134{
135  int i;
136 
137  omRetInfo_t info[OM_MAX_BACKTRACE_DEPTH];
138  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
139 
140  i = omBackTrace_2_RetInfo(bt, info, max);
141  return omPrintRetInfo(info, i, fd, "  #%i %L in %F\n");
142}
143
144int omPrintCurrentBackTrace(FILE* fd)
145{
146  int i;
147  void* bt[OM_MAX_BACKTRACE_DEPTH];
148 
149  i = omGetBackTrace(bt, 1, OM_MAX_BACKTRACE_DEPTH);
150  return omPrintBackTrace(bt, i, fd);
151}
152
153/*************************************************************
154 *                                                             
155 * Various Filters
156 *
157 *************************************************************/
158int omFilterRetInfo_i(omRetInfo info, int max, int i)
159{
160  int j=0, k=i;
161 
162  while (k < max)
163  {
164    info[j] = info[k];
165    j++;
166    k++;
167  }
168  return j;
169}
170
171/*************************************************************
172 *                                                             
173 * Low level routines
174 *
175 *************************************************************/
176
177int _omPrintBackTrace(void** bt, int max, FILE* fd , OM_FLR_DECL)
178{
179  int i;
180 
181  omRetInfo_t info[OM_MAX_BACKTRACE_DEPTH];
182  if (max > OM_MAX_BACKTRACE_DEPTH) max = OM_MAX_BACKTRACE_DEPTH;
183 
184  i = omBackTrace_2_RetInfo(bt, info, max);
185#ifdef OM_TRACK_RETURN
186  if (i == 0)
187    i = omBackTrace_2_RetInfo(&r,info, 1);
188#endif
189#ifndef OM_INTERNAL_DEBUG
190  if (i > 1)
191  {
192#ifdef OM_TRACK_RETURN
193    if (r != NULL)
194      omFilterRetInfo(info, i, addr_i == r);
195#endif
196#ifdef OM_TRACK_FILE_LINE
197    if (f != NULL && l > 0)
198      omFilterRetInfo(info, i, strcmp(f, file_i) == 0 && l + 2 >= line_i && l - 2 <= line_i);
199#endif
200    /* if we have both, use overwrite what we got from return addressse --
201       they sometimes are wrong */
202#if defined(OM_TRACK_RETURN) && defined(OM_TRACK_FILE_LINE)
203    if (r != NULL && info[0].addr == r && l > 0 && f != 0)
204    {
205      strcpy(info[0].file, f);
206      info[0].line = l;
207    }
208#endif 
209  }
210  if (i == 0)
211  {
212#endif /* ! OM_INTERNAL_DEBUG */
213
214#ifdef OM_TRACK_FILE_LINE
215    fprintf(fd, " %s:%d", f, l);
216#endif
217#ifdef OM_TRACK_RETURN
218    fprintf(fd," ra=%p");
219#endif
220
221#ifndef OM_INTERNAL_DEBUG
222    return 1;
223  }
224  else
225#endif /* ! OM_INTERNAL_DEBUG */
226    return omPrintRetInfo(info, i, fd, "\n  #%i at %L in %F ra=%p");
227}
228
229int _omPrintCurrentBackTrace(FILE* fd , OM_FLR_DECL)
230{
231  int i;
232  void* bt[OM_MAX_BACKTRACE_DEPTH];
233 
234  i = omGetBackTrace(bt, 1, OM_MAX_BACKTRACE_DEPTH);
235  return _omPrintBackTrace(bt, i, fd , OM_FLR_VAL);
236}
237
238#endif /* ! OM_NDEBUG */
239 
240 
241
242
243   
244   
245     
246   
247
Note: See TracBrowser for help on using the repository browser.