source: git/omalloc/omTrack.c @ 212fc04

spielwiese
Last change on this file since 212fc04 was 212fc04, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* as we go along git-svn-id: file:///usr/local/Singular/svn/trunk@3878 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.4 KB
Line 
1/*******************************************************************
2 *  File:    omTrack.c
3 *  Purpose: routines for getting Backtraces of stack
4 *  Author:  obachman (Olaf Bachmann)
5 *  Created: 11/99
6 *  Version: $Id: omTrack.c,v 1.2 1999-11-22 18:13:00 obachman Exp $
7 *******************************************************************/
8#include <limits.h>
9
10#include "omConfig.h"
11#include "omFindExec.h"
12#include "omPrivate.h"
13
14#ifndef MAXPATHLEN
15#define MAXPATHLEN 1024
16#endif
17
18/* This is for nice alignment of omPrintBackTrace */
19#define OM_MAX_PROC_NAME_LENGTH 20
20/* if you make this larger than 11, extend OM_GET_RETURN_ADDR and
21   OM_GET_FRAME_ADDR */
22#define OM_MAX_BT_FRAMES 11
23
24#ifdef OM_RETURN_ADDR_RVALUE
25#define OM_GET_RETURN_ADDR OM_RETURN_ADDR
26#else
27#define OM_GET_RETURN_ADDR(addr, i)             \
28switch(i)                                       \
29{                                               \
30    case 0:                                     \
31      addr = OM_RETURN_ADDR(0); break;          \
32    case 1:                                     \
33      addr = OM_RETURN_ADDR(1); break;          \
34    case 2:                                     \
35      addr = OM_RETURN_ADDR(2); break;          \
36    case 3:                                     \
37      addr = OM_RETURN_ADDR(3); break;          \
38    case 4:                                     \
39      addr = OM_RETURN_ADDR(4); break;          \
40    case 5:                                     \
41      addr = OM_RETURN_ADDR(5); break;          \
42    case 6:                                     \
43      addr = OM_RETURN_ADDR(6); break;          \
44    case 7:                                     \
45      addr = OM_RETURN_ADDR(7); break;          \
46    case 8:                                     \
47      addr = OM_RETURN_ADDR(8); break;          \
48    case 9:                                     \
49      addr = OM_RETURN_ADDR(9); break;          \
50    case 10:                                    \
51      addr = OM_RETURN_ADDR(10); break;         \
52    default:                                    \
53      addr = NULL;                              \
54}
55#endif /* OM_RETURN_ADDR_RVALUE */
56
57#ifdef OM_FRAME_ADDR_RVALUE
58#define OM_GET_FRAME_ADDR OM_FRAME_ADDR
59#else
60#define OM_GET_FRAME_ADDR(addr, i)              \
61switch(i)                                       \
62{                                               \
63    case 0:                                     \
64      addr = OM_FRAME_ADDR(0); break;           \
65    case 1:                                     \
66      addr = OM_FRAME_ADDR(1); break;           \
67    case 2:                                     \
68      addr = OM_FRAME_ADDR(2); break;           \
69    case 3:                                     \
70      addr = OM_FRAME_ADDR(3); break;           \
71    case 4:                                     \
72      addr = OM_FRAME_ADDR(4); break;           \
73    case 5:                                     \
74      addr = OM_FRAME_ADDR(5); break;           \
75    case 6:                                     \
76      addr = OM_FRAME_ADDR(6); break;           \
77    case 7:                                     \
78      addr = OM_FRAME_ADDR(7); break;           \
79    case 8:                                     \
80      addr = OM_FRAME_ADDR(8); break;           \
81    case 9:                                     \
82      addr = OM_FRAME_ADDR(9); break;           \
83    case 10:                                    \
84      addr = OM_FRAME_ADDR(10); break;          \
85    default:                                    \
86      addr = NULL;                              \
87}
88#endif /* OM_FRAME_ADDR_RVALUE */
89
90static char* om_this_prog = NULL;
91static void* om_this_main_frame_addr = NULL;
92static void* om_this_prog_min_return_addr = ((void*) 1023);
93static void* om_this_prog_max_return_addr = ((void*) ULONG_MAX -1);
94
95
96void omInitTrack(const char* argv0)
97{
98  char buf[MAXPATHLEN];
99 
100  if (argv0 != NULL && omFindExec(argv0, buf))
101  {
102    __omTypeAllocChunk(char*, om_this_prog, strlen(buf));
103    strcpy(om_this_prog, buf);
104  }
105#if defined(OM_FRAME_ADDR_WORKS)
106  om_this_main_frame_addr = OM_FRAME_ADDR(1);
107#endif
108#if defined(OM_PROG_NM) && defined(HAVE_POPEN)
109  if (om_this_prog != NULL)
110  {
111    char command[MAXPATHLEN + 30];
112    FILE *pipe;
113    sprintf(command, "%s -n %s", OM_PROG_NM, om_this_prog);
114   
115    pipe = popen(command, "r");
116    if (pipe != NULL)
117    {
118      /* serach for first address */
119      int c;
120      void* nm_addr;
121      while ( (c=fgetc(pipe)) !=  EOF)
122      {
123        if (c == '\n')
124        {
125          if (fscanf(pipe, "%p", &nm_addr) && 
126              (unsigned long) nm_addr > 
127              (unsigned long) om_this_prog_min_return_addr)
128          {
129            om_this_prog_min_return_addr = nm_addr;
130            break;
131          }
132        }
133      }
134      om_this_prog_max_return_addr = nm_addr;
135      while ( (c=fgetc(pipe)) !=  EOF)
136      {
137        if (c == '\n')
138        {
139          if (fscanf(pipe, "%p", &nm_addr) && nm_addr != NULL &&
140              (unsigned long) nm_addr  > 
141              (unsigned long) om_this_prog_max_return_addr)
142          {
143            om_this_prog_max_return_addr = nm_addr;
144          }
145        }
146      }
147      pclose(pipe);
148    }
149  }
150#endif /* defined(OM_NM) && defined(HAVE_POPEN) */
151}
152
153
154int omGetCurrentBackTrace(void** addr, int max_frames)
155{
156  int i = 0;
157#if defined(OM_RETURN_ADDR_WORKS)
158#if defined(OM_FRAME_ADDR_WORKS)
159  if (om_this_main_frame_addr != NULL)
160  {
161    void* this_frame = OM_FRAME_ADDR(0);
162    if (this_frame == 0) return 0;
163    else
164    {
165#endif /* ! defined(OM_RETURN_ADDR_WORKS) */
166      void* r_addr;
167      if (max_frames > OM_MAX_BT_FRAMES) max_frames = OM_MAX_BT_FRAMES;
168      for (i=0; i< max_frames; i++)
169      {
170        OM_GET_RETURN_ADDR(r_addr, i);
171        if (r_addr > om_this_prog_min_return_addr &&
172            r_addr < om_this_prog_max_return_addr)
173          addr[i] = r_addr;
174        else
175        {
176          addr[i] = NULL;
177          return i;
178        }
179#ifdef OM_FRAME_ADDR_WORKS
180        OM_GET_FRAME_ADDR(r_addr, i + 1);
181        /* check that next frame is in really between main and this_frame */
182        if ((r_addr >= om_this_main_frame_addr && 
183             om_this_main_frame_addr >= this_frame) ||
184            (r_addr <= om_this_main_frame_addr && 
185             om_this_main_frame_addr <= this_frame))
186        {
187          if (i+1 < max_frames) addr[i+1] = NULL;
188          return i + 1;
189        }
190      }
191    }
192#endif /* OM_FRAME_ADDR_WORKS */
193  }
194#endif /* defined(OM_RETURN_ADDR_WORKS) */
195  return i;
196}
197
198int omPrintBackTrace(void** addr, int max_frames, FILE* fd)
199{
200  int i = 0;
201  if (max_frames > OM_MAX_BT_FRAMES) max_frames = OM_MAX_BT_FRAMES;
202#if defined(HAVE_POPEN) && defined(OM_PROG_ADDR2LINE)
203  if (om_this_prog != NULL)
204  {
205    char command[2*MAXPATHLEN + 15 + OM_MAX_BT_FRAMES*(2*SIZEOF_VOIDP + 4)];
206    FILE *pipe;
207    int l;
208    l = sprintf(command, "%s -s -C -f -e %s", 
209                     OM_PROG_ADDR2LINE, om_this_prog);
210
211    while (i<max_frames && addr[i] != NULL)
212    {
213      l += sprintf(&command[l], " %p", addr[i]);
214      i++;
215    }
216   
217    if (i > 0)
218    {
219      pipe = popen(command, "r");
220      if (pipe != NULL)
221      {
222        int nl = 0;
223        int j = 0;
224        int k=0;
225        while ((l=fgetc(pipe)) != EOF)
226        {
227          if (nl == 0) 
228          {
229            fprintf(fd, "  #%d %p in ", j, addr[j]);
230            nl = 1;
231            j++;
232            k=0;
233          }
234          if (l == '\n')
235          {
236            if (nl == 1)
237            {
238              while (k<OM_MAX_PROC_NAME_LENGTH)
239              {
240                fprintf(fd, " ");
241                k++;
242              }
243              fprintf(fd, " at ");
244              nl = 2;
245            }
246            else
247            {
248              fputc('\n', fd);
249              nl = 0;
250            }
251          }
252          else
253          {
254            k++;
255            fputc(l, fd);
256          }
257        }
258        pclose(pipe);
259        fflush(fd);
260        return i;
261      }
262      i=0;
263    }
264  }
265#endif
266#if OM_RETURN_ADDR_WORKS
267  while (i<max_frames && addr[i] != NULL)
268  {
269    fprintf(fd, "  #%d %p in ??\n", i, addr[i]);
270    i++;
271  }
272#endif
273  if (i == 0) 
274  {
275    fprintf(fd, "??");
276    fputc('\n', fd);
277  }
278  fflush(fd);
279  return i;
280}
281
282int omPrintCurrentBackTrace(int from_frame, int max_frames, FILE *fd)
283{
284  void* addr[OM_MAX_BT_FRAMES];
285  int got_frames = omGetCurrentBackTrace(addr, from_frame + max_frames + 1);
286  return omPrintBackTrace(&addr[from_frame + 1], 
287                          got_frames - from_frame + 1, fd);
288}
289
290 
291
292   
293   
294     
295   
296
Note: See TracBrowser for help on using the repository browser.