Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 355731
Collapse All | Expand All

(-)a/babl/babl-memory.c (+112 lines)
Lines 16-21 Link Here
16
 * <http://www.gnu.org/licenses/>.
16
 * <http://www.gnu.org/licenses/>.
17
 */
17
 */
18
18
19
#define _GNU_SOURCE 1
20
19
#include "config.h"
21
#include "config.h"
20
#include <stdint.h>
22
#include <stdint.h>
21
#include <stdlib.h>
23
#include <stdlib.h>
Lines 23-28 Link Here
23
#include <string.h>
25
#include <string.h>
24
#include "babl-internal.h"
26
#include "babl-internal.h"
25
27
28
#include <sys/types.h>
29
#include <unistd.h>
30
#include <sys/ptrace.h>
31
#include <linux/ptrace.h>
32
#include <sys/user.h>
33
#include <sys/debugreg.h>
34
#include <assert.h>
35
#include <unistd.h>
36
#include <errno.h>
37
#include <signal.h>
38
26
static BablMallocFunc malloc_f = malloc;
39
static BablMallocFunc malloc_f = malloc;
27
static BablFreeFunc   free_f   = free;
40
static BablFreeFunc   free_f   = free;
28
41
Lines 32-43 static void *first_free_used = NULL; Link Here
32
void
45
void
33
babl_set_malloc (BablMallocFunc malloc_function)
46
babl_set_malloc (BablMallocFunc malloc_function)
34
{
47
{
48
  fprintf (stderr,
49
           "babl_set_malloc:\n"
50
           " first_malloc_used: %p\n"
51
           " old malloc_f:      %p\n"
52
           " malloc_function:   %p\n",
53
           first_malloc_used, malloc_f, malloc_function);
35
  malloc_f = malloc_function;
54
  malloc_f = malloc_function;
36
}
55
}
37
56
38
void
57
void
39
babl_set_free (BablFreeFunc free_function)
58
babl_set_free (BablFreeFunc free_function)
40
{
59
{
60
  fprintf (stderr,
61
           "babl_set_free:\n"
62
           " first_free_used:   %p\n"
63
           " old free_f:        %p\n"
64
           " free_function:     %p\n",
65
           first_free_used, free_f, free_function);
41
  free_f = free_function;
66
  free_f = free_function;
42
}
67
}
43
68
Lines 78-83 mem_stats (void) Link Here
78
103
79
#endif
104
#endif
80
105
106
static void set_watchpoint(void* addr) {
107
  /* Thanks to jankratochvil in #gdb@freenode who pointed this out:
108
     http://sources.redhat.com/cgi-bin/cvsweb.cgi/~checkout~/tests/ptrace-tests/tests/watchpoint.c?cvsroot=systemtap
109
  */
110
111
  pid_t child;
112
  int status;
113
  unsigned long dr7;
114
  long l;
115
116
  child = fork ();
117
  switch (child)
118
    {
119
    case -1:
120
      assert (0);
121
    case 0:
122
      assert (ptrace (PTRACE_TRACEME, 0, NULL, NULL) == 0);
123
      assert (raise (SIGTRAP) == 0);
124
125
      return;
126
    default:
127
      break;
128
    }
129
130
  assert (waitpid (child, &status, 0) == child);
131
  assert (WIFSTOPPED (status));
132
  assert (WSTOPSIG (status) == SIGTRAP);
133
134
  errno = 0;
135
  l = ptrace (PTRACE_POKEUSER, child,
136
	      offsetof (struct user, u_debugreg[0]), (unsigned long) addr);
137
  assert_perror (errno);
138
  assert (l == 0);
139
140
  dr7 = (DR_RW_WRITE << DR_CONTROL_SHIFT);
141
142
#ifdef DR_LEN_8
143
  /*
144
   * For a 32-bit build, DR_LEN_8 might be defined by the header.
145
   * On a 64-bit kernel, we might even be able to use it.
146
   * But we can't tell, and we don't really need it, so just use DR_LEN_4.
147
   */
148
  if (sizeof (long) > 4)
149
    dr7 |= (DR_LEN_8 << DR_CONTROL_SHIFT);
150
  else
151
#endif
152
    dr7 |= (DR_LEN_4 << DR_CONTROL_SHIFT);
153
  dr7 |= (1UL << DR_LOCAL_ENABLE_SHIFT);
154
  dr7 |= (1UL << DR_GLOBAL_ENABLE_SHIFT);
155
156
  l = ptrace (PTRACE_POKEUSER, child, offsetof (struct user, u_debugreg[7]), dr7);
157
  assert_perror (errno);
158
  assert (l == 0);
159
160
  errno = 0;
161
  l = ptrace (PTRACE_CONT, child, 0l, 0l);
162
  assert_perror (errno);
163
  assert (l == 0);
164
165
  exit(0);
166
}
167
81
static void
168
static void
82
functions_sanity (void)
169
functions_sanity (void)
83
{
170
{
Lines 86-96 functions_sanity (void) Link Here
86
    {
173
    {
87
      if (first_malloc_used == NULL)
174
      if (first_malloc_used == NULL)
88
        {
175
        {
176
          fprintf (stderr,
177
                   "First use of malloc:\n"
178
                   " first_malloc_used: %p\n"
179
                   " malloc_f:          %p\n"
180
                   " first_free_used:   %p\n"
181
                   " free_f:            %p\n",
182
                   first_malloc_used, malloc_f, first_free_used, free_f);
183
          /*
184
          fprintf (stderr, "Please attach debugger to pid %lu and press enter",
185
                   (unsigned long)getpid());
186
          {
187
            char buf[30];
188
            fgets(buf, sizeof(buf), stdin);
189
          }
190
          */
89
          first_malloc_used = malloc_f;
191
          first_malloc_used = malloc_f;
90
          first_free_used   = free_f;
192
          first_free_used   = free_f;
193
          fprintf (stderr, "Watching for writes to %p\n", &malloc_f);
194
          set_watchpoint(&malloc_f);
91
        }
195
        }
92
      else
196
      else
93
        {
197
        {
198
          fprintf (stderr,
199
                   "babl memory function(s) attempted switched on the fly:\n"
200
                   " first_malloc_used: %p\n"
201
                   " malloc_f:          %p\n"
202
                   " first_free_used:   %p\n"
203
                   " free_f:            %p\n",
204
                   first_malloc_used, malloc_f, first_free_used, free_f);
205
          abort ();
94
          babl_fatal ("babl memory function(s) attempted switched on the fly");
206
          babl_fatal ("babl memory function(s) attempted switched on the fly");
95
        }
207
        }
96
    }
208
    }

Return to bug 355731