Debug improvements

This commit is contained in:
rfm 2024-06-21 16:43:50 +01:00
parent 50e1575b8d
commit d49b6a46ce
4 changed files with 34 additions and 27 deletions

View file

@ -6,6 +6,12 @@
* Tools/make_strings/make_strings.m:
* Tools/plutil.m:
Fix various memory leaks.
* Tools/NSObject.m:
* Documentation/Base.gsdoc:
Make GSLogZombie() an external function for debuggers which can't find
it as a static function. Add [NSZombie -logZombie:] method to call the
function in case there is a debugger which can set a breakpoint on the
method more easily than on the function.
2024-06-21 Richard Frith-Macdonald <rfm@gnu.org>

View file

@ -509,11 +509,13 @@ notice and this notice are preserved.
<p>
If this is set to YES, then deallocation of an object causes
the object to be morphed into a Zombie ... a special object
which will call the GNUstep specific GSLogZombie() function
to log the method call.<br />
of class NSZombie whose -logZombie: method will call the
GNUstep specific GSLogZombie() function to log the method
call.<br />
If GNUstep-base was built for debugging (make debug=yes),
you can set a breakpoint in this function and examine the
process memory when you are running under a debugger.<br />
you can set a breakpoint in this method or function and
examine the process memory when you are running under a
debugger.<br />
As this overrides actual object deallocation, all memory
allocated for objects will be leaked unless the
NSDeallocateZombies environment variable is also set.<br />

View file

@ -743,35 +743,30 @@ _GSDebugAllocationRemove(Class c, id o)
the_table[i].bytes -= bytes;
if (the_table[i].num_recorded_objects > 0)
{
unsigned j, k, n;
unsigned j, n;
n = the_table[i].num_recorded_objects;
for (j = 0; j < n; j++)
/* Most objects have a brief lifespan. It therefore
* makes sense to search from the end of the array back
* to the start to maximise the chance of finding an
* object quickly.
*/
j = n = the_table[i].num_recorded_objects;
while (j-- > 0)
{
if ((the_table[i].recorded_objects)[j] == o)
{
tag = (the_table[i].recorded_tags)[j];
while (++j < n)
{
(the_table[i].recorded_objects)[j - 1] =
(the_table[i].recorded_objects)[j];
(the_table[i].recorded_tags)[j - 1] =
(the_table[i].recorded_tags)[j];
}
the_table[i].num_recorded_objects--;
break;
}
}
if (j < n)
{
for (k = j + 1; k < n; k++)
{
(the_table[i].recorded_objects)[k - 1] =
(the_table[i].recorded_objects)[k];
(the_table[i].recorded_tags)[k - 1] =
(the_table[i].recorded_tags)[k];
}
the_table[i].num_recorded_objects--;
}
else
{
/* Not found - no problem - this happens if the
object was allocated before we started
recording */
;
}
}
unLock();
[tag release];

View file

@ -157,7 +157,7 @@ static void GSMakeZombie(NSObject *o, Class c)
}
#endif
static void GSLogZombie(id o, SEL sel)
extern void GSLogZombie(id o, SEL sel)
{
Class c = 0;
@ -2473,13 +2473,17 @@ static id gs_weak_load(id obj)
}
return c;
}
- (void) logZombie: (SEL)selector
{
GSLogZombie(self, selector);
}
- (void) forwardInvocation: (NSInvocation*)anInvocation
{
NSUInteger size = [[anInvocation methodSignature] methodReturnLength];
unsigned char v[size];
memset(v, '\0', size);
GSLogZombie(self, [anInvocation selector]);
[self logZombie: [anInvocation selector]];
[anInvocation setReturnValue: (void*)v];
return;
}