[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ 100307 ] Dynamic loading of .framework broken?
From: |
nobody |
Subject: |
[ 100307 ] Dynamic loading of .framework broken? |
Date: |
Sat, 12 Jan 2002 22:18:52 -0500 |
Support Request #100307, was updated on 2002-Jan-12 22:18
You can respond by visiting:
http://savannah.gnu.org/support/?func=detailsupport&support_id=100307&group_id=99
Category: Foundation
Status: Open
Priority: 5
Summary: Dynamic loading of .framework broken?
By: kaelin
Date: 2002-Jan-12 22:18
Message:
Logged In: NO
Browser: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.5) Gecko/20011014
The NSBundle (Private) method _addFrameworkFromClass:
gets called in the callback chain from dlopen when a
framework is dynamically loaded, e.g.:
NSBundle * classBundle = [NSBundle bundleWithPath:
@"/usr/share/pvm3/Library/Frameworks/FWBench.framework"];
if ([classBundle load]) {
...
}
In the current CVS version of the Foundation sources,
_addFrameworkFromClass: tries and (at least in some
common cases) fails to reconstruct bundlePath from thin
air, then ends up trying to allocate a new NSBundle
instance with a nil path. Initially this is just logged
as a warning, but eventually this leads to a SEGV.
I have made a stab at fixing the immediate problem, and
my code is included here. This fix does appear to work
for me, BUT I am concerned that it might have unforseen
consequences in use cases I'm just not exercising... or
that it's completely the wrong thing because I don't
know the runtime architecture well enough to muck with
this!
My changes are explained in the comments...
+ (BOOL) _addFrameworkFromClass:(Class)frameworkClass
{
int len;
if (frameworkClass == Nil)
return NO;
len = strlen(frameworkClass->name);
if (len > 12*sizeof(char)
&& !strncmp("NSFramework_", frameworkClass->name,
sizeof(char)*12))
{
NSBundle *bundle = _loadingBundle;
NSString **fmClasses;
/*
* This following block used to be executed
unconditionally, and
* would ultimately fail when a framework's code
was being
* dynamically loaded because it was allocating a
new NSBundle
* instance and initializing its path to nil. Now
we are first
* checking _loadingBundle, and if non-nil we
initialize the
* existing bundle instead of creating a new one.
* -- Kaelin 01/13/2002
*/
if (bundle == nil) {
NSString *bundlePath = nil;
NSString *varEnv, *path, *name;
name = [NSString stringWithCString:
&frameworkClass->name[12]];
varEnv = [frameworkClass frameworkEnv];
if (varEnv && [varEnv length])
bundlePath = [[[NSProcessInfo processInfo] environment]
objectForKey: varEnv];
path = [frameworkClass frameworkPath];
if (path && [path length])
{
if (bundlePath)
bundlePath = [bundlePath
stringByAppendingPathComponent: path];
else
bundlePath = path;
}
else
bundlePath = [bundlePath
stringByAppendingPathComponent: @"Library/Frameworks"];
bundlePath = [bundlePath stringByAppendingPathComponent:
[NSString stringWithFormat: @"%@.framework", name]];
bundle = [[NSBundle alloc] initWithPath: bundlePath];
}
bundle->_bundleType = NSBUNDLE_FRAMEWORK;
bundle->_codeLoaded = YES;
bundle->_frameworkVersion =
RETAIN([frameworkClass frameworkVersion]);
bundle->_bundleClasses = RETAIN([NSMutableArray
arrayWithCapacity: 2]);
fmClasses = [frameworkClass frameworkClasses];
while (*fmClasses)
{
NSValue *value;
Class class = NSClassFromString(*fmClasses);
value = [NSValue valueWithNonretainedObject: class];
[(NSMutableArray *)[bundle _bundleClasses] addObject:
value];
#if 0 /*
* This isn't needed anymore, because now if we're
loading a
* bundle, that's the one we just updated...
*/
if (_loadingBundle)
{
NSEnumerator *classEnum;
NSValue *obj;
classEnum = [_loadingBundle->_bundleClasses
objectEnumerator];
while ((obj = [classEnum nextObject]))
{
if ([obj nonretainedObjectValue] == class)
{
[(NSMutableArray *)_loadingBundle->_bundleClasses
removeObject: obj];
break;
}
}
}
#endif
fmClasses++;
}
return YES;
}
return NO;
}
----------------------------------------------------------------------
You can respond by visiting:
http://savannah.gnu.org/support/?func=detailsupport&support_id=100307&group_id=99
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [ 100307 ] Dynamic loading of .framework broken?,
nobody <=