source: git/omalloc/omTrack.c @ 66502b8

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