Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Indent include and src using this command:
[simgrid.git] / src / xbt / mmalloc / mmtrace.c
1 /* More debugging hooks for `mmalloc'.
2    Copyright 1991, 1992, 1994 Free Software Foundation
3
4    Written April 2, 1991 by John Gilmore of Cygnus Support
5    Based on mcheck.c by Mike Haertel.
6    Modified Mar 1992 by Fred Fish.  (fnf@cygnus.com) */
7
8 /* Copyright (c) 2010. The SimGrid Team.
9  * All rights reserved.                                                     */
10
11 /* This program is free software; you can redistribute it and/or modify it
12  * under the terms of the license (GNU LGPL) which comes with this package. */
13
14 #include <stdio.h>
15 #include "mmprivate.h"
16
17 static void tr_break(void);
18 static void tr_freehook(void *md, void *ptr);
19 static void *tr_mallochook(void *md, size_t size);
20 static void *tr_reallochook(void *md, void *ptr, size_t size);
21
22 #ifndef __GNU_LIBRARY__
23 extern char *getenv();
24 #endif
25
26 static FILE *mallstream;
27
28 #if 0                           /* FIXME:  Disabled for now. */
29 static char mallenv[] = "MALLOC_TRACE";
30 static char mallbuf[BUFSIZ];    /* Buffer for the output.  */
31 #endif
32
33 /* Address to breakpoint on accesses to... */
34 static void *mallwatch;
35
36 /* Old hook values.  */
37
38 static void (*old_mfree_hook) (void *md, void *ptr);
39 static void *(*old_mmalloc_hook) (void *md, size_t size);
40 static void *(*old_mrealloc_hook) (void *md, void *ptr, size_t size);
41
42 /* This function is called when the block being alloc'd, realloc'd, or
43    freed has an address matching the variable "mallwatch".  In a debugger,
44    set "mallwatch" to the address of interest, then put a breakpoint on
45    tr_break.  */
46
47 static void tr_break(void)
48 {
49 }
50
51 static void tr_freehook(void *md, void *ptr)
52 {
53   struct mdesc *mdp;
54
55   mdp = MD_TO_MDP(md);
56   /* Be sure to print it first.  */
57   fprintf(mallstream, "- %08lx\n", (unsigned long) ptr);
58   if (ptr == mallwatch)
59     tr_break();
60   mdp->mfree_hook = old_mfree_hook;
61   mfree(md, ptr);
62   mdp->mfree_hook = tr_freehook;
63 }
64
65 static void *tr_mallochook(void *md, size_t size)
66 {
67   void *hdr;
68   struct mdesc *mdp;
69
70   mdp = MD_TO_MDP(md);
71   mdp->mmalloc_hook = old_mmalloc_hook;
72   hdr = (void *) mmalloc(md, size);
73   mdp->mmalloc_hook = tr_mallochook;
74
75   /* We could be printing a NULL here; that's OK.  */
76   fprintf(mallstream, "+ %p 0x%lx\n", hdr, (unsigned long) size);
77
78   if (hdr == mallwatch)
79     tr_break();
80
81   return (hdr);
82 }
83
84 static void *tr_reallochook(void *md, void *ptr, size_t size)
85 {
86   void *hdr;
87   struct mdesc *mdp;
88
89   mdp = MD_TO_MDP(md);
90
91   if (ptr == mallwatch)
92     tr_break();
93
94   mdp->mfree_hook = old_mfree_hook;
95   mdp->mmalloc_hook = old_mmalloc_hook;
96   mdp->mrealloc_hook = old_mrealloc_hook;
97   hdr = (void *) mrealloc(md, ptr, size);
98   mdp->mfree_hook = tr_freehook;
99   mdp->mmalloc_hook = tr_mallochook;
100   mdp->mrealloc_hook = tr_reallochook;
101   if (hdr == NULL)
102     /* Failed realloc.  */
103     fprintf(mallstream, "! %p 0x%lx\n", ptr, (unsigned long) size);
104   else
105     fprintf(mallstream, "< %p\n> %p 0x%lx\n", ptr,
106             hdr, (unsigned long) size);
107
108   if (hdr == mallwatch)
109     tr_break();
110
111   return hdr;
112 }
113
114 /* We enable tracing if either the environment variable MALLOC_TRACE
115    is set, or if the variable mallwatch has been patched to an address
116    that the debugging user wants us to stop on.  When patching mallwatch,
117    don't forget to set a breakpoint on tr_break!  */
118
119 int mmtrace(void)
120 {
121 #if 0                           /* FIXME!  This is disabled for now until we figure out how to
122                                    maintain a stack of hooks per heap, since we might have other
123                                    hooks (such as set by mmcheck/mmcheckf) active also. */
124   char *mallfile;
125
126   mallfile = getenv(mallenv);
127   if (mallfile != NULL || mallwatch != NULL) {
128     mallstream = fopen(mallfile != NULL ? mallfile : "/dev/null", "w");
129     if (mallstream != NULL) {
130       /* Be sure it doesn't mmalloc its buffer!  */
131       setbuf(mallstream, mallbuf);
132       fprintf(mallstream, "= Start\n");
133       old_mfree_hook = mdp->mfree_hook;
134       mdp->mfree_hook = tr_freehook;
135       old_mmalloc_hook = mdp->mmalloc_hook;
136       mdp->mmalloc_hook = tr_mallochook;
137       old_mrealloc_hook = mdp->mrealloc_hook;
138       mdp->mrealloc_hook = tr_reallochook;
139     }
140   }
141 #endif                          /* 0 */
142
143   return (1);
144 }