Added experimental stacktrace printing support.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22878 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2006-05-08 15:30:52 +00:00
parent db4d168095
commit 5dac5f97a9
6 changed files with 872 additions and 8 deletions

View file

@ -1,3 +1,12 @@
2006-05-08 Richard Frith-Macdonald <rfm@gnu.org>
* configure.ac: Check for bfd stuff for stacktrace support.
* Source/NSException.m: incorporate code by Lloyd Dupont and Wim
Oudshoorn to add a stack trace to a raised exception. Cleaned up
and made to conform to coding standards. Rewrote code to build
list of binary files from NSBundle.
EXPERIMENTAL! Turn this on by building with STACKTRACE defined
2006-05-07 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSBundle.m: ignore profile/debug extensions in library name

View file

@ -39,6 +39,9 @@
/* Define if this constant is defined */
#undef HANDLE_LONG_LONG_MAX
/* Define to 1 if you have the <bfd.h> header file. */
#undef HAVE_BFD_H
/* Define to 1 if you have the <callback.h> header file. */
#undef HAVE_CALLBACK_H
@ -94,6 +97,9 @@
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
/* Define to 1 if you have the `inet_pton' function. */
#undef HAVE_INET_PTON
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
@ -109,12 +115,18 @@
/* Define to 1 if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
/* Define to 1 if you have the `bfd' library (-lbfd). */
#undef HAVE_LIBBFD
/* Define to 1 if you have the <libc.h> header file. */
#undef HAVE_LIBC_H
/* Define to 1 if you have the `dl' library (-ldl). */
#undef HAVE_LIBDL
/* Define to 1 if you have the `iberty' library (-liberty). */
#undef HAVE_LIBIBERTY
/* Define to 1 if you have the `kvm' library (-lkvm). */
#undef HAVE_LIBKVM
@ -442,9 +454,11 @@
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t

View file

@ -993,9 +993,10 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory)
*/
+ (NSBundle *) bundleForClass: (Class)aClass
{
void* key;
NSBundle* bundle;
void *key;
NSBundle *bundle;
NSMapEnumerator enumerate;
if (!aClass)
return nil;

View file

@ -18,21 +18,530 @@
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
$Date$ $Revision$
*/
#include "config.h"
#include "GNUstepBase/preface.h"
#include <Foundation/NSDebug.h>
#include <Foundation/NSBundle.h>
#include "Foundation/NSException.h"
#include "Foundation/NSString.h"
#include "Foundation/NSArray.h"
#include "Foundation/NSCoder.h"
#include "Foundation/NSNull.h"
#include "Foundation/NSThread.h"
#include "Foundation/NSDictionary.h"
#include <stdio.h>
/*
* Turn off STACKTRACE if we don't have bfd support for it.
*/
#if !(defined(HAVE_BFD_H) && defined(HAVE_LIBBFD) && defined(HAVE_LIBIBERTY))
#if defined(STACKTRACE)
#undef STACKTRACE
#endif
#endif
#if defined(STACKTRACE)
// GSStackTrace inspired by FYStackTrace.m
// created by Wim Oudshoorn on Mon 11-Apr-2006
// reworked by Lloyd Dupont @ NovaMind.com on 4-May-2006
#include <bfd.h>
@class GSBinaryFileInfo;
@interface GSFunctionInfo : NSObject
{
void *_address;
NSString *_fileName;
NSString *_functionName;
int _lineNo;
GSBinaryFileInfo *_module;
}
- (void*) address;
- (NSString *) fileName;
- (NSString *) function;
- (id) initWithModule: (GSBinaryFileInfo*)module
address: (void*)address
file: (NSString*)file
function: (NSString*)function
line: (int)lineNo;
- (int) lineNumber;
- (GSBinaryFileInfo*) module;
@end
@interface GSBinaryFileInfo : NSObject
{
NSString *_filename;
bfd *_abfd;
asymbol **_symbols;
long _symbolCount;
}
- (NSString *) filename;
- (GSFunctionInfo *) functionForAddress: (void*) address;
- (id) initWithBinaryFile: (NSString *)filename;
- (id) init; // return info for the current executing process
@end
@interface GSStackTrace : NSObject
{
NSMutableArray *frames;
}
+ (GSStackTrace*) currentStack;
/*
* Add some module information to the stack trace information
* only symbols from the current process's file, GNUstep base library,
* GNUstep gui library, and any bundles containing code are loaded.
* All other symbols should be manually added
*/
+ (BOOL) loadModule: (NSString *)filename;
- (NSString*) description;
- (NSEnumerator*) enumerator;
- (GSFunctionInfo*) frameAt: (unsigned)index;
- (unsigned) frameCount;
- (NSEnumerator*) reverseEnumerator;
@end
@implementation GSFunctionInfo
- (void*) address
{
return _address;
}
- (oneway void) dealloc
{
[_module release];
_module = nil;
[_fileName release];
_fileName = nil;
[_functionName release];
_functionName = nil;
[super dealloc];
}
- (NSString *) description
{
return [NSString stringWithFormat: @"(%@: %p) %@ %@: %d",
[_module filename], _address, _functionName, _fileName, _lineNo];
}
- (NSString *) fileName
{
return _fileName;
}
- (NSString *) function
{
return _functionName;
}
- (id) init
{
[self release];
return nil;
}
- (id) initWithModule: (GSBinaryFileInfo*)module
address: (void*)address
file: (NSString*)file
function: (NSString*)function
line: (int)lineNo
{
_module = [module retain];
_address = address;
_fileName = [file retain];
_functionName = [function retain];
_lineNo = lineNo;
return self;
}
- (int) lineNumber
{
return _lineNo;
}
- (GSBinaryFileInfo *) module
{
return _module;
}
@end
@implementation GSBinaryFileInfo
+ (GSBinaryFileInfo*) infoWithBinaryFile: (NSString *)filename
{
return [[[self alloc] initWithBinaryFile: filename] autorelease];
}
+ (void) initialize
{
static BOOL first = YES;
if (first == NO)
{
return;
}
first = NO;
bfd_init ();
}
- (oneway void) dealloc
{
[_filename release];
_filename = nil;
if (_abfd)
{
bfd_close (_abfd);
_abfd = NULL;
}
if (_symbols)
{
free (_symbols);
_symbols = NULL;
}
[super dealloc];
}
- (NSString *) filename
{
return _filename;
}
- (id) init
{
NSString *processName;
processName = [[[NSProcessInfo processInfo] arguments] objectAtIndex: 0];
return [self initWithBinaryFile: processName];
}
- (id) initWithBinaryFile: (NSString *)filename
{
int neededSpace;
// 1st initialize the bfd
if ([filename length] == 0)
{
NSLog (@"GSBinaryFileInfo: No File");
[self release];
return nil;
}
_filename = [filename copy];
_abfd = bfd_openr ([filename cString], NULL);
if (!_abfd)
{
NSLog (@"GSBinaryFileInfo: No Binary Info");
[self release];
return nil;
}
if (!bfd_check_format_matches (_abfd, bfd_object, NULL))
{
NSLog (@"GSBinaryFileInfo: BFD format object error");
[self release];
return nil;
}
// second read the symbols from it
if (!(bfd_get_file_flags (_abfd) & HAS_SYMS))
{
NSLog (@"GSBinaryFileInfo: BFD does not contain any symbols");
[self release];
return nil;
}
neededSpace = bfd_get_symtab_upper_bound (_abfd);
if (neededSpace < 0)
{
NSLog (@"GSBinaryFileInfo: BFD error while deducing needed space");
[self release];
return nil;
}
if (neededSpace == 0)
{
NSLog (@"GSBinaryFileInfo: BFD no space for symbols needed");
[self release];
return nil;
}
_symbols = malloc (neededSpace);
if (!_symbols)
{
NSLog (@"GSBinaryFileInfo: Can't malloc buffer");
[self release];
return nil;
}
_symbolCount = bfd_canonicalize_symtab (_abfd, _symbols);
if (_symbolCount < 0)
{
NSLog (@"GSBinaryFileInfo: BFD error while reading symbols");
[self release];
return nil;
}
return self;
}
struct SearchAddressStruct
{
void *theAddress;
GSBinaryFileInfo *module;
asymbol **symbols;
GSFunctionInfo *theInfo;
};
static void find_address (bfd *abfd, asection *section,
struct SearchAddressStruct *info)
{
bfd_vma address;
bfd_vma vma;
unsigned size;
const char *fileName;
const char *functionName;
unsigned line = 0;
if (info->theInfo)
{
return;
}
if (!(bfd_get_section_flags (abfd, section) & SEC_ALLOC))
{
return;
}
address = (bfd_vma) info->theAddress;
vma = bfd_get_section_vma (abfd, section);
size = bfd_get_section_size (section);
if (address < vma || address >= vma + size)
{
return;
}
if (bfd_find_nearest_line (abfd, section, info->symbols,
address - vma, &fileName, &functionName, &line))
{
GSFunctionInfo *fi;
fi = [GSFunctionInfo alloc];
fi = [fi initWithModule: info->module
address: info->theAddress
file: [NSString stringWithCString: fileName]
function: [NSString stringWithCString: functionName]
line: line];
[fi autorelease];
info->theInfo = fi;
}
}
- (GSFunctionInfo *) functionForAddress: (void*) address
{
struct SearchAddressStruct searchInfo = { address, self, _symbols, nil };
bfd_map_over_sections (_abfd,
(void (*) (bfd *, asection *, void *)) find_address, &searchInfo);
return searchInfo.theInfo;
}
@end
// this method automatically load the current process + GNUstep base & gui.
static NSMutableDictionary *GetStackModules()
{
static NSMutableDictionary *stackModules = nil;
if (stackModules == nil)
{
NSEnumerator *enumerator;
NSBundle *bundle;
stackModules = [NSMutableDictionary new];
/*
* Try to ensure we have the main, base and gui library bundles.
*/
[NSBundle mainBundle];
[NSBundle bundleForClass: [NSObject class]];
[NSBundle bundleForClass: NSClassFromString(@"NSView")];
/*
* Add file info for all bundles with code.
*/
enumerator = [[NSBundle allBundles] objectEnumerator];
while ((bundle = [enumerator nextObject]) != nil)
{
if ([bundle load] == YES)
{
[GSStackTrace loadModule: [bundle executablePath]];
}
}
}
return stackModules;
}
@implementation GSStackTrace : NSObject
static NSNull *null = nil;
+ (GSStackTrace*) currentStack
{
return [[[GSStackTrace alloc] init] autorelease];
}
+ (void) initialize
{
null = RETAIN([NSNull null]);
}
// initialize stack trace info
+ (BOOL) loadModule: (NSString *)filename
{
if ([filename length] > 0)
{
NSMutableDictionary *modules = GetStackModules();
if ([modules objectForKey: filename] == nil)
{
GSBinaryFileInfo *module;
module = [GSBinaryFileInfo infoWithBinaryFile: filename];
if (module != nil)
{
[modules setObject: module forKey: filename];
}
else
{
[modules setObject: null forKey: filename];
}
}
if ([modules objectForKey: filename] != null)
{
return YES;
}
}
return NO;
}
- (oneway void) dealloc
{
[frames release];
frames = nil;
[super dealloc];
}
- (NSString*) description
{
NSMutableString *result = [NSMutableString string];
int i;
int n;
n = [frames count];
for (i = 0; i < n; i++)
{
GSFunctionInfo *line = [frames objectAtIndex: i];
[result appendFormat: @"%3d: %@\n", i, line];
}
return result;
}
- (NSEnumerator*) enumerator
{
return [frames objectEnumerator];
}
- (GSFunctionInfo*) frameAt: (unsigned)index
{
return [frames objectAtIndex: index];
}
- (unsigned) frameCount
{
return [frames count];
}
// grab the current stack
// this MAX_FRAME comes from NSDebug.h which warn only 100 frames are available
#define MAX_FRAME 100
- (id) init
{
NSArray *modules;
int i;
int j;
int n;
int m;
frames = [[NSMutableArray alloc] init];
modules = [GetStackModules() allValues];
n = NSCountFrames();
m = [modules count];
for (i = 0; i < n && i < MAX_FRAME; i++)
{
GSFunctionInfo *aFrame = nil;
void *address = NSReturnAddress(i);
for (j = 0; j < m; j++)
{
GSBinaryFileInfo *bfi = [modules objectAtIndex: j];
if ((id)bfi != (id)null)
{
aFrame = [bfi functionForAddress: address];
if (aFrame)
{
[frames addObject: aFrame];
break;
}
}
}
// not found (?!), add an 'unknown' function
if (!aFrame)
{
aFrame = [GSFunctionInfo alloc];
[aFrame initWithModule: nil
address: address
file: nil
function: nil
line: 0];
[aFrame autorelease];
[frames addObject: aFrame];
}
}
return self;
}
- (NSEnumerator*) reverseEnumerator
{
return [frames reverseObjectEnumerator];
}
@end
#endif /* STACKTRACE */
NSString* const NSGenericException
= @"NSGenericException";
@ -141,12 +650,37 @@ _NSFoundationUncaughtExceptionHandler (NSException *exception)
- (void) raise
{
#ifndef _NATIVE_OBJC_EXCEPTIONS
NSThread *thread;
NSHandler *handler;
#endif
#if defined(STACKTRACE)
if ([_e_info objectForKey: @"GSStackTraceKey"] == nil)
{
NSMutableDictionary *m;
if (_e_info == nil)
{
_e_info = m = [NSMutableDictionary new];
}
else if ([_e_info isKindOfClass: [NSMutableDictionary class]] == YES)
{
m = (NSMutableDictionary*)_e_info;
}
else
{
m = [_e_info mutableCopy];
RELEASE(_e_info);
_e_info = m;
}
[m setObject: [GSStackTrace currentStack] forKey: @"GSStackTraceKey"];
}
#endif
#ifdef _NATIVE_OBJC_EXCEPTIONS
@throw self;
#else
NSThread *thread;
NSHandler *handler;
thread = GSCurrentThread();
handler = thread->_exception_handler;
if (handler == NULL)

299
configure vendored
View file

@ -9693,6 +9693,305 @@ fi
done
#--------------------------------------------------------------------
# These headers/functions needed for stacktrace in NSException.m
#--------------------------------------------------------------------
for ac_header in bfd.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
# Is the header compilable?
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
# Is the header present?
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------------ ##
## Report this to the AC_PACKAGE_NAME lists. ##
## ------------------------------------------ ##
_ASBOX
) |
sed "s/^/$as_me: WARNING: /" >&2
;;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
echo "$as_me:$LINENO: checking for dyn_string_append in -liberty" >&5
echo $ECHO_N "checking for dyn_string_append in -liberty... $ECHO_C" >&6
if test "${ac_cv_lib_iberty_dyn_string_append+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-liberty $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char dyn_string_append ();
int
main ()
{
dyn_string_append ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_iberty_dyn_string_append=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_iberty_dyn_string_append=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_iberty_dyn_string_append" >&5
echo "${ECHO_T}$ac_cv_lib_iberty_dyn_string_append" >&6
if test $ac_cv_lib_iberty_dyn_string_append = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBIBERTY 1
_ACEOF
LIBS="-liberty $LIBS"
fi
echo "$as_me:$LINENO: checking for bfd_openr in -lbfd" >&5
echo $ECHO_N "checking for bfd_openr in -lbfd... $ECHO_C" >&6
if test "${ac_cv_lib_bfd_bfd_openr+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lbfd $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char bfd_openr ();
int
main ()
{
bfd_openr ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_bfd_bfd_openr=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_bfd_bfd_openr=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_bfd_bfd_openr" >&5
echo "${ECHO_T}$ac_cv_lib_bfd_bfd_openr" >&6
if test $ac_cv_lib_bfd_bfd_openr = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBBFD 1
_ACEOF
LIBS="-lbfd $LIBS"
fi
#--------------------------------------------------------------------
# These headers/functions needed by NSLog.m
#--------------------------------------------------------------------

View file

@ -770,6 +770,13 @@ fi
AC_CHECK_HEADERS(sys/socket.h netinet/in.h)
dnl AC_REPLACE_FUNCS(recvfrom)
#--------------------------------------------------------------------
# These headers/functions needed for stacktrace in NSException.m
#--------------------------------------------------------------------
AC_CHECK_HEADERS(bfd.h)
AC_CHECK_LIB(iberty, dyn_string_append)
AC_CHECK_LIB(bfd, bfd_openr)
#--------------------------------------------------------------------
# These headers/functions needed by NSLog.m
#--------------------------------------------------------------------