source: git/omalloc/omRet2Info.c @ b6e039

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