source: git/omalloc/omRet2Info.c @ 8291be

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