bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#1079: GNUstep port segfaults making autoloads on x86_64


From: Yavor Doganov
Subject: bug#1079: GNUstep port segfaults making autoloads on x86_64
Date: Tue, 07 Oct 2008 22:02:51 +0300
User-agent: Wanderlust/2.15.5 (Almost Unreal) SEMI/1.14.6 (Maruoka) FLIM/1.14.9 (Gojō) APEL/10.7 Emacs/22.3 (i486-pc-linux-gnu) MULE/5.0 (SAKAKI)

Glenn Morris wrote:
> 
> > Which version of GNUstep Base is this?
> 
> gnustep-startup-0.20.0.tar

That should contain the latest stable releases, so it must be OK (I've
never installed this way, though.)

> base/NSInvocation/general.m:
> FAIL: Can send/return large structs

This is a bit worrisome.  Just to rule out the possibility, can you
compile gnustep-base against libffi in case it was built with
libffcall (and vice-versa -- rebuild it with libffcall if it was with
libffi).  There were numerous problems with both, and libffi became
preferred by upstream a few months ago.

> > Does the naive patch below eliminate this problem?
>
> I'm afraid not.

Oh, of course not; this file is not being read at all at this point.
Nevertheless, still fixes a harmless runtime warning.

> Here is a full backtrace this time:

Thanks.  I can't see how this can be a bug in Emacs.  The arguments of
bootstrap-emacs are evaluated as property lists and since "(setq foo
1)" (or whatever is passed to --batch in such form) is not a validly
formatted array, an NSException is raised here:

#5  0x00002b51204f9fbb in GSPropertyListFromStringsFormat (string=0x1b392730)
    at NSPropertyList.m:1505
        dict = (class NSMutableDictionary *) 0x0
        _pld = {
  ptr = 0x1b281c70 "(setq foo 1)", 
  end = 12, 
  pos = 0, 
  lin = 0, 
  err = 0x2b512095f000, 
  opt = NSPropertyListImmutable, 
  key = 0 '\000', 
  old = 1 '\001'
}

However, this exception should be caught and handled by the parent
exception handler at NSUserDefaults.m:1814 -- note the comment there:

          else
            {                            // Real parameter                      
              /* Parsing the argument as a property list is very                
                 delicate.  We *MUST NOT* crash here just because a             
                 strange parameter (such as `(load "test.scm")`) is             
                 passed, otherwise the whole library is useless in a            
                 foreign environment. */
              NSObject *plist_val;

              NS_DURING
              [....]

This is precisely the case here, and it's handled properly on i386.

It is getting too complicated for me, but can you compile this test
program (it should never crash):

test.m:
=======
#import <Foundation/Foundation.h>

int
main (int argc, char** argv, char **env)
{
  NSAutoreleasePool *pool = [NSAutoreleasePool new];
  NSProcessInfo     *proc = [NSProcessInfo processInfo];
  NSBundle        *bundle = [NSBundle mainBundle];
  NSArray           *args;
  unsigned              i;
  int              retval = 0;

  [NSProcessInfo initializeWithArguments:argv
                 count:argc
                 environment:env];

  args = [proc arguments];
  GSPrintf (stderr, @"Useless info about bundle: %@\n", bundle);

  if ([args count] <= 1)
    {
      GSPrintf (stderr, @"Please specify some arguments.\n");
      RELEASE (pool);
      exit (EXIT_FAILURE);
    }
  else if ([[proc environment] valueForKey:@"NOHANDLE"] != nil)
    GSPrintf (stderr, @"NOHANDLE defined; should exit with success.\n");
  else
    {
      for (i = 1; i < [args count]; i++)
        {
          NSString      *opt = [args objectAtIndex: i];

          NS_DURING
            {
              NSString  *tempString;
              id        result;

              tempString = [NSString stringWithString: opt];
              if (tempString == nil)
                GSPrintf (stderr, @"This should not happen.\n");
              /* Exception handler taking care here.  */
              else if (![tempString propertyList]); 
              else if ((result = [tempString propertyList]) == nil)
                GSPrintf (stderr, @"'%@' - a nil property list.\n", opt);
              else if ([result isKindOfClass: [NSDictionary class]] == YES)
                GSPrintf (stderr, @"'%@' - a dictionary.\n", opt);
              else if ([result isKindOfClass: [NSArray class]] == YES)
                GSPrintf (stderr, @"'%@' - an array.\n", opt);
              else if ([result isKindOfClass: [NSString class]] == YES)
                GSPrintf (stderr, @"'%@' - a string.\n", opt);
              else
                GSPrintf (stderr, @"'%@' - unknown class %@.\n",
                  opt, [[result class] description]);
            }
          NS_HANDLER
            {
              GSPrintf (stderr, @"'%@' failed with:\n%@.\n", opt,
                [localException reason]);
              GSPrintf (stderr, @"Failure.\n");
              retval = 1;
            }
          NS_ENDHANDLER
        }
    }
  RELEASE (pool);
  return retval;
}

You can use this simple makefile to build it:

GNUmakefile:
============
include $(GNUSTEP_MAKEFILES)/common.make
TOOL_NAME = test
test_OBJC_FILES = test.m
include $(GNUSTEP_MAKEFILES)/tool.make

Just type `make'.

Then test it as follows (the executable should be /obj/test):

(gdb) r '{a=b; c=d}' '(foo, bar)' --batch '(setq foo 1)'
...
(gdb) set environment NOHANDLE=yes
(gdb) r   (with the same arguments)

Thanks.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]