Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Unify the copyright headers of mmalloc with the rest of the library
[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
48 tr_break (void)
49 {
50 }
51
52 static void
53 tr_freehook (void *md, void *ptr)
54 {
55   struct mdesc *mdp;
56
57   mdp = MD_TO_MDP (md);
58   /* Be sure to print it first.  */
59   fprintf (mallstream, "- %08lx\n", (unsigned long) ptr);
60   if (ptr == mallwatch)
61     tr_break ();
62   mdp -> mfree_hook = old_mfree_hook;
63   mfree (md, ptr);
64   mdp -> mfree_hook = tr_freehook;
65 }
66
67 static void*
68 tr_mallochook (void* md, size_t size)
69 {
70   void* hdr;
71   struct mdesc *mdp;
72
73   mdp = MD_TO_MDP (md);
74   mdp -> mmalloc_hook = old_mmalloc_hook;
75   hdr = (void*) mmalloc (md, size);
76   mdp -> mmalloc_hook = tr_mallochook;
77
78   /* We could be printing a NULL here; that's OK.  */
79   fprintf (mallstream, "+ %p 0x%lx\n", hdr, (unsigned long)size);
80
81   if (hdr == mallwatch)
82     tr_break ();
83
84   return (hdr);
85 }
86
87 static void*
88 tr_reallochook (void *md, void *ptr, size_t size)
89 {
90   void* hdr;
91   struct mdesc *mdp;
92
93   mdp = MD_TO_MDP (md);
94
95   if (ptr == mallwatch)
96     tr_break ();
97
98   mdp -> mfree_hook = old_mfree_hook;
99   mdp -> mmalloc_hook = old_mmalloc_hook;
100   mdp -> mrealloc_hook = old_mrealloc_hook;
101   hdr = (void*) mrealloc (md, ptr, size);
102   mdp -> mfree_hook = tr_freehook;
103   mdp -> mmalloc_hook = tr_mallochook;
104   mdp -> mrealloc_hook = tr_reallochook;
105   if (hdr == NULL)
106     /* Failed realloc.  */
107     fprintf (mallstream, "! %p 0x%lx\n", ptr, (unsigned long) size);
108   else
109     fprintf (mallstream, "< %p\n> %p 0x%lx\n", ptr,
110              hdr, (unsigned long) size);
111
112   if (hdr == mallwatch)
113     tr_break ();
114
115   return hdr;
116 }
117
118 /* We enable tracing if either the environment variable MALLOC_TRACE
119    is set, or if the variable mallwatch has been patched to an address
120    that the debugging user wants us to stop on.  When patching mallwatch,
121    don't forget to set a breakpoint on tr_break!  */
122
123 int
124 mmtrace (void)
125 {
126 #if 0   /* FIXME!  This is disabled for now until we figure out how to
127            maintain a stack of hooks per heap, since we might have other
128            hooks (such as set by mmcheck/mmcheckf) active also. */
129   char *mallfile;
130
131   mallfile = getenv (mallenv);
132   if (mallfile  != NULL || mallwatch != NULL)
133     {
134       mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w");
135       if (mallstream != NULL)
136         {
137           /* Be sure it doesn't mmalloc its buffer!  */
138           setbuf (mallstream, mallbuf);
139           fprintf (mallstream, "= Start\n");
140           old_mfree_hook = mdp -> mfree_hook;
141           mdp -> mfree_hook = tr_freehook;
142           old_mmalloc_hook = mdp -> mmalloc_hook;
143           mdp -> mmalloc_hook = tr_mallochook;
144           old_mrealloc_hook = mdp -> mrealloc_hook;
145           mdp -> mrealloc_hook = tr_reallochook;
146         }
147     }
148
149 #endif  /* 0 */
150
151   return (1);
152 }
153