[OGo-GNUstep-Port] experiences with OGo and gunstep-base on OpenBSD
Sebastian Reitenbach
gnustep-port@opengroupware.org
Mon, 28 May 2007 12:21:05 +0200
Hi,
I updated the GNUstep ports that are available for OpenBSD 4.1, containing
the latest gnustep-make 2.0.1 and gnustep-base 1.15.0.[1] I created
additional ports for Sope, mod_ngobjweb and OGo[2]. The ports are based on
the trunk versions of sope and ogo. They all compile and install fine.
After compiling and configuring, ogo did started successfully. but after
trying to login, it crashed. It took me some while to not install stripped
versions of it, to be able to debug the problem.
There seems to be two problems:
1. in gnustep-base NSAutoreleasePool.m:404
2. in gnustep-base NSKeyValueCoding.m:350
commenting out these two lines and recompiling, then everything seems to
work. I was able to login, search contacts, write mail, ....
below the gdb stack traces from the crashes and exception:
(gdb) bt
#0 0x00000000 in ?? ()
#1 0x08284718 in -[NSAutoreleasePool emptyPool] (self=0x81e8b888,
_cmd=0x282eba10) at NSAutoreleasePool.m:404
#2 0x08284492 in -[NSAutoreleasePool dealloc] (self=0x81e8b888,
_cmd=0x282eba08) at NSAutoreleasePool.m:323
#3 0x08284447 in -[NSAutoreleasePool release] (self=0x81e8b888,
_cmd=0x240b04b8) at NSAutoreleasePool.m:316
#4 0x040b59ae in -[LSDBFetchRelationCommand _executeInContext:]
(self=0x8a28f808, _cmd=0x29979b80, _context=0x8b5a1208)
at LSDBFetchRelationCommand.m:287
#5 0x09984a63 in -[LSFetchExtendedAttributesCommand _executeInContext:]
(self=0x8a28f808, _cmd=0x240b0bc8, _context=0x8b5a1208)
at LSFetchExtendedAttributesCommand.m:145
#6 0x040b75de in -[LSDBObjectBaseCommand primaryRunInContext:]
(self=0x8a28f808, _cmd=0x240ae798, _context=0x8b5a1208)
at LSDBObjectBaseCommand.m:186
#7 0x040add8c in -[LSBaseCommand runInContext:] (self=0x8a28f808,
_cmd=0x240ae6f8, _context=0x8b5a1208) at LSBaseCommand.m:192
#8 0x040ad678 in LSCommandRunV (_ctx=0x8b5a1208, _factory=0x83ac3b08,
_domain=0x2fa2df18, _command=0x2fa2df24) at LSBaseCommand.m:84
#9 0x0fa3108d in -[LSLoginAccountCommand _executeInContext:]
(self=0x8b5a1808, _cmd=0x240b0bc8, _context=0x8b5a1208)
at LSLoginAccountCommand.m:249
#10 0x040b75de in -[LSDBObjectBaseCommand primaryRunInContext:]
(self=0x8b5a1808, _cmd=0x240ae798, _context=0x8b5a1208)
at LSDBObjectBaseCommand.m:186
#11 0x040add8c in -[LSBaseCommand runInContext:] (self=0x8b5a1808,
_cmd=0x240af6f0, _context=0x8b5a1208) at LSBaseCommand.m:192
#12 0x040b23ce in runCommand (self=0x8b5a1208, _command=0x8b5a1808) at
LSCommandContext.m:870
#13 0x040b0957 in -[LSCommandContext runCommand:vargs:] (self=0x8b5a1208,
_cmd=0x240b9a00, _command=0x240b9bf4, _va=0xcfbdc890)
at LSCommandContext.m:457
...
(gdb) list NSAutoreleasePool.m:404
399 else
400 {
401 imps[hash] = [c methodForSelector:
releaseSel];
402 }
403 }
404 (imps[hash])(anObject, releaseSel);
405 }
406 _released_count -= released->count;
407 released->count = 0;
408 released = released->next;
- (void) emptyPool
{
unsigned i;
Class classes[16];
IMP imps[16];
for (i = 0; i < 16; i++)
{
classes[i] = 0;
imps[i] = 0;
}
/*
* Loop throught the deallocation code repeatedly ... since we deallocate
* objects in the receiver while the receiver remains set as the current
* autorelease pool ... so if any object which is being deallocated adds
* any object to the current autorelease pool, we may need to release it
* again.
*/
while (_child != nil || _released_count > 0)
{
volatile struct autorelease_array_list *released = _released_head;
/* If there are NSAutoreleasePool below us in the stack of
NSAutoreleasePools, then deallocate them also. The (only) way we
could get in this situation (in correctly written programs, that
don't release NSAutoreleasePools in weird ways), is if an
exception threw us up the stack. */
if (_child != nil)
{
[_child dealloc];
}
/* Take the object out of the released list just before releasing it,
* so if we are doing "double_release_check"ing, then
* autoreleaseCountForObject: won't find the object we are currently
* releasing. */
while (released != 0)
{
id *objects = (id*)(released->objects);
for (i = 0; i < released->count; i++)
{
id anObject = objects[i];
Class c = GSObjCClass(anObject);
unsigned hash = (((unsigned)(uintptr_t)c) >> 3) & 0x0f;
objects[i] = nil;
if (classes[hash] != c)
{
classes[hash] = c;
if (GSObjCIsInstance(anObject))
{
imps[hash] = [c instanceMethodForSelector:
releaseSel];
}
else
{
imps[hash] = [c methodForSelector: releaseSel];
}
}
(imps[hash])(anObject, releaseSel);
}
_released_count -= released->count;
released->count = 0;
released = released->next;
}
}
}
- (void)_executeInContext:(id)_context {
NSString *relKey;
NSArray *rels;
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
relKey = [self relationKey];
rels = [self _fetchRelations];
// TODO: move section to an own method
if (![self isToMany] && (relKey != nil)) {
NSString *srcKey, *destKey, *relKey;
NSArray *objs;
int i, cnt;
srcKey = [self sourceKey];
destKey = [self destinationKey];
relKey = [self relationKey];
objs = [self object];
for (i = 0, cnt = [objs count]; i < cnt; i++) {
id obj, pKey;
int j, cnt2;
obj = [objs objectAtIndex:i];
pKey = [obj valueForKey:srcKey];
for (j = 0, cnt2 = [rels count]; j < cnt2; j++) {
NSNumber *fKey;
id relObj;
relObj = [rels objectAtIndex:j];
fKey = [relObj valueForKey:destKey];
if (![pKey isEqual:fKey])
continue;
[obj takeValue:relObj forKey:relKey];
}
}
}
if (relKey == nil)
[self setReturnValue:rels];
[pool release]; pool = nil;
}
2007-05-28 12:03:11.906 ogo-webui-1.1[25601] Note: using flat-array message
notifications!
[Switching to process 25601, thread 0x8b81b000]
Breakpoint 1, -[NSException raise] (self=0x881e4148, _cmd=0x251b9020) at
NSException.m:782
782 if (GSPrivateEnvironmentFlag("GNUSTEP_STACK_TRACE", NO) == YES
Current language: auto; currently objective-c
(gdb) bt
#0 -[NSException raise] (self=0x881e4148, _cmd=0x251b9020) at
NSException.m:782
#1 0x051b3ff9 in -[NSObject(KeyValueCoding) setValue:forUndefinedKey:]
(self=0x86d58108, _cmd=0x251e0110, anObject=0x86d58528,
aKey=0x881e40e8) at NSKeyValueCoding.m:350
#2 0x05269beb in GSObjCSetVal (self=0x86d58108, key=0xcfbf98a0 "misc",
val=0x86d58528, sel=0x0, type=0x0, size=4, offset=-809527136)
at GSObjCRuntime.m:1810
#3 0x051b320e in SetValueForKey (self=0x86d58108, anObject=0x86d58528,
key=0xcfbf98a0 "misc", size=4) at NSKeyValueCoding.m:114
#4 0x051b3c0f in -[NSObject(KeyValueCoding) setValue:forKey:]
(self=0x86d58108, _cmd=0x263a8fe8, anObject=0x86d58528, aKey=0x86d58128)
at NSKeyValueCoding.m:288
#5 0x063efbf5 in _setValue (self=0x80f4ba08, _value=0x86d58528,
root=0x8917f988) at WOKeyPathAssociation.m:912
#6 0x063efddd in -[WOKeyPathAssociation setValue:inComponent:]
(self=0x80f4ba08, _cmd=0x26391790, _value=0x86d58528, _component=0x8917f988)
at WOKeyPathAssociation.m:934
#7 0x063993d5 in WOComponent_syncToParent (self=0x83157588,
_parent=0x8917f988) at WOComponent+Sync.m:174
#8 0x0639da12 in WOContext_leaveComponent (self=0x80644808,
_component=0x83157588) at WOContext.m:444
#9 0x0639dc57 in -[WOContext leaveComponent:] (self=0x80644808,
_cmd=0x263b09e0, _component=0x83157588) at WOContext.m:469
(gdb) list NSKeyValueCoding.m:350
345 (aKey ? (id)aKey : (id)@"(nil)"), @"NSUnknownUserInfoKey",
346 nil];
347 exp = [NSException exceptionWithName: NSInvalidArgumentException
348 reason: @"Unable to set nil value
for key"
349 userInfo: dict];
350 [exp raise];
351 }
352
353
354 - (void) setValuesForKeysWithDictionary: (NSDictionary*)aDictionary
- (void) setValue: (id)anObject forUndefinedKey: (NSString*)aKey
{
NSDictionary *dict;
NSException *exp;
static IMP o = 0;
/* Backward compatibility hack */
if (o == 0)
{
o = [NSObject instanceMethodForSelector:
@selector(handleTakeValue:forUnboundKey:)];
}
if ([self methodForSelector: @selector(handleTakeValue:forUnboundKey:)] !=
o)
{
[self handleTakeValue: anObject forUnboundKey: aKey];
return;
}
dict = [NSDictionary dictionaryWithObjectsAndKeys:
(anObject ? (id)anObject : (id)@"(nil)"), @"NSTargetObjectUserInfoKey",
(aKey ? (id)aKey : (id)@"(nil)"), @"NSUnknownUserInfoKey",
nil];
exp = [NSException exceptionWithName: NSInvalidArgumentException
reason: @"Unable to set nil value for key"
userInfo: dict];
[exp raise];
}
well, I doubt that commenting out the two mentioned lines above is the
correct solution, but as I do not really understood the memory management
yet, I have no idea for a better solution.
I also have no clue, whether this is gnustep-base fault, or whether there is
sth. incorrectly usesd in sope/OGo. Any hint would be appreciated.
kind regards
Sebastian
[1]
http://docs.opengroupware.org/Members/buzzdee/openbsd/GNUstep%20ports%20for%20OpenBSD/document_view
[2]
http://docs.opengroupware.org/Members/buzzdee/openbsd/OGo%20ports%20for%20OpenBSD/document_view