[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
possible NSInvocation bugs
From: |
Stephen Brandon |
Subject: |
possible NSInvocation bugs |
Date: |
Tue, 19 Feb 2002 18:16:01 +0000 |
Hi,
I'm just trying to get my head around the way NSInvocation works on GNUstep,
cos it seems to not be doing what it should.
I'm trying to do a "retainArguments" on an invocation that will be queued up
and sent in another thread. The rest of the system works ok - it just that
the extra retains are not being added to the arguments, and sometimes they go
and get released before the invocation is sent - kaboom on the other end.
I'm on a fresh install of RedHat linux 7.2, using gcc-2.96. I have compiled
and installed the ffcall package.
here's the code chunk:
[anInvocation setSelector:sel];
[anInvocation setTarget:target];
[anInvocation setArgument:&arg1 atIndex:2];
[anInvocation setArgument:&arg2 atIndex:3];
[anInvocation retainArguments];
Breakpoint 2, _i_NSInvocation__retainArguments (self=0x853fc58,
_cmd=0x403508e8) at NSInvocation.m:362
362 if (_argsRetained)
(gdb) next
370 _argsRetained = YES;
(gdb)
371 IF_NO_GC(RETAIN(_target));
(gdb)
372 if (_argframe == 0)
(gdb)
374 return;
(gdb)
407 }
(gdb) p *self
$17 = {isa = 0x40646b60, _sig = 0x8341b58, _argframe = 0x0, _cframe =
0x8167e00, _retval = 0x8167e40,
_target = 0x813ab88, _selector = 0x40352c10, _numArgs = 4, _info =
0x8494bb0, _argsRetained = 1 '\001',
_validReturn = 0 '\000', _sendToSuper = 0 '\000'}
... so the first problem here is that it's checking for _argframe as a proof
of (perhaps?) whether or not the arguments have been set. I don't completely
understand how this all works, but it's clear that either _argframe should
have been set somewhere else, or it should not be checked here.
Suggested solution:
NSInvocation.m:37c
change: if (_argframe == 0)
to: if (_argframe == 0 && _cframe == 0)
since I think that the object will use either argframes or cframes
depending on which backend implementation is being used.
Second problem:
If I do the -retainArguments call *before* setting the arguments, I get a
segfault when I set argument atIndex:3. Tracing this through, it does the
following:
_i_NSInvocation__setArgument_atIndex_ (self=0x8276b78, _cmd=0x403508d8,
buffer=0xbfffcb10, index=2)
at NSInvocation.m:250
250 if ((unsigned)index >= _numArgs)
(gdb) step
255 if (index == 0)
(gdb)
259 else if (index == 1)
(gdb)
265 int i = index+1; /* Allow for return type in
'_info' */
(gdb)
266 const char *type = _info[i].type;
(gdb)
268 if (_argsRetained && (*type == _C_ID || *type == _C_CHARPTR))
(gdb) p type
$4 = 0x8341b67 "@8@12" (so it's definitely an id type)
(gdb) step
270 if (*type == _C_ID)
(gdb)
274 _get_arg(self, index, &old);
(gdb) step
_get_arg (inv=0x8276b78, index=2, buffer=0xbfffca9c) at NSInvocation.m:69
69 callframe_get_arg((callframe_t *)inv->_cframe, index, buffer,
(gdb) list
65 #elif defined(USE_FFCALL)
66 static inline void
67 _get_arg(NSInvocation *inv, int index, void *buffer)
68 {
69 callframe_get_arg((callframe_t *)inv->_cframe, index, buffer,
70 inv->_info[index+1].size);
71 }
(gdb) step
71 }
(gdb)
_i_NSInvocation__setArgument_atIndex_ (self=0x8276b78, _cmd=0x403508d8,
buffer=0xbfffcb10, index=2)
at NSInvocation.m:275
275 _set_arg(self, index, buffer);
(gdb) p *old
Cannot access memory at address 0x680073
(gdb) p old
$12 = 0x680073
(gdb) step
_set_arg (inv=0x8276b78, index=2, buffer=0xbfffcb10) at NSInvocation.m:76
76 callframe_set_arg((callframe_t *)inv->_cframe, index, buffer,
(gdb) step
78 }
(gdb)
_i_NSInvocation__setArgument_atIndex_ (self=0x8276b78, _cmd=0x403508d8,
buffer=0xbfffcb10, index=2)
at NSInvocation.m:276
276 IF_NO_GC(RETAIN(*(id*)buffer));
(gdb) step
277 if (old != nil)
(gdb) step
279 RELEASE(old);
(gdb) step
Program received signal SIGSEGV, Segmentation fault.
... Oooops - looks like callframe_get_arg() had grabbed back an invalid 'old'
value, which causes a crash when released.
Sorry, I have no idea how to address this one!
Any help appreciated. I'm pretty confident I have the 1st problem solved with
the patch mentioned, but the second one is more difficult!
Cheers,
Stephen Brandon
- possible NSInvocation bugs,
Stephen Brandon <=