1 //========================================================================
5 // Copyright 2000-2001 Emmanuel Lesueur
7 //========================================================================
15 GDebug::Context
*GDebug::Context::current
;
17 struct GDebug::Tracker::Tracked
{
19 const char ** context
;
22 struct GDebug::Tracker::TrackedArray
{
23 TrackedArray() : array(NULL
), size(0), max(0) {}
25 for (int k
= 0; k
< size
; ++k
)
26 Context::free(array
[k
].context
);
34 GDebug::Tracker::Tracker() : tracked(new TrackedArray
[size
]) {
37 GDebug::Tracker::~Tracker() {
38 for (int i
= 0; i
< size
; ++i
) {
39 for (int k
= 0; k
< tracked
[i
].size
; ++k
) {
40 fprintf(stderr
, "Object %lx not freed. Allocated at:\n", tracked
[i
].array
[k
].object
);
41 Context::print(tracked
[i
].array
[k
].context
);
42 fprintf(stderr
, "\n");
43 show(tracked
[i
].array
[k
].object
);
49 void GDebug::Tracker::show(void*) {}
51 void GDebug::Tracker::track(void *object
) {
52 int hash
= ((unsigned)object
>> 4) % size
;
54 if (tracked
[hash
].size
== tracked
[hash
].max
) {
55 int sz
= tracked
[hash
].size
* 2 + 16;
56 Tracked
*p
= new Tracked
[sz
];
57 if (tracked
[hash
].size
)
58 memcpy(p
, tracked
[hash
].array
, sizeof(*p
) * tracked
[hash
].size
);
59 delete [] tracked
[hash
].array
;
60 tracked
[hash
].array
= p
;
61 tracked
[hash
].max
= sz
;
64 tracked
[hash
].array
[tracked
[hash
].size
].object
= object
;
65 tracked
[hash
].array
[tracked
[hash
].size
].context
= Context::save();
69 void GDebug::Tracker::unTrack(void *object
) {
70 int hash
= ((unsigned)object
>> 4) % size
;
72 for (int k
= 0; k
< tracked
[hash
].size
; ++k
) {
73 if (tracked
[hash
].array
[k
].object
== object
) {
74 delete [] tracked
[hash
].array
[k
].context
;
75 if (k
< tracked
[hash
].size
- 1)
76 memmove(tracked
[hash
].array
+ k
, tracked
[hash
].array
+ k
+ 1,
77 (tracked
[hash
].size
- k
- 1) * sizeof(tracked
[hash
].array
[0]));
84 fprintf(stderr
, "Object %lx has not been allocated !\n", object
);
85 throw "Internal Error";
88 const char **GDebug::Context::save() {
91 for (Context
*c
= current
; c
; c
= c
->prev
)
94 p
= new const char * [n
+ 1];
96 const char **q
= p
+ n
;
98 for (Context
*c
= current
; c
; c
= c
->prev
)
106 void GDebug::Context::print(const char **context
) {
107 fprintf(stderr
, "*");
109 fprintf(stderr
, " / %s", *context
);
114 void GDebug::Context::traceBack() {
115 Context
*context
= current
;
117 fprintf(stderr
, "%s <- ", context
->name
);
118 context
= context
->prev
;
120 fprintf(stderr
, "*");