discuss-gnustep
[Top][All Lists]
Advanced

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

Re: GWorkspace hangs on first exit attempt. Remote objects problem?


From: Fred Kiefer
Subject: Re: GWorkspace hangs on first exit attempt. Remote objects problem?
Date: Sat, 09 Mar 2013 17:57:32 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130215 Thunderbird/17.0.3

On 09.03.2013 16:30, Sebastian Reitenbach wrote:

On Saturday, March 9, 2013 15:44 CET, Richard Frith-Macdonald 
<richard@tiptree.demon.co.uk> wrote:


On 9 Mar 2013, at 12:20, Fred Kiefer wrote:

here I checked:
(gdb) p [invocation->_sig isOneway]
$7 = 1 '\001'

so it appears that the information about oneway is properly passed, right?
(gdb) p invocation->_sig->_methodTypes
$9 = 0x17a9c30 "Vv24@0:8@16"

Is this enough? In case not you need to tell me which part to inspect.


I think the interesting stuff happens in frame 4. There we end up in the 
needsResponse == YES branch, which seems wrong for a one way method call. You 
should have a look at the block from line 2016 to 2039 and find out why 
needsResponse gets set to YES. Most likely the method type gets compute 
wrongly. We seem to get these strange results sometimes from libobjc2.

Yes ... I can't reproduce  the problem on any system I have apaer from the 
debian 64bit one where I recently installed using llvm/clang and libobjc2.
So this seems to be either an llvm/clang specific issue or a libobjc2 specific 
issue, with the code going wrong later on (ie the invocation itsself seems 
fine).

I also see the problem on my macppc, using libobjc2 but compiled with gcc 4.2.1.

As Fred

       needsResponse = NO;
       flags = objc_get_type_qualifiers(type);
NSLog(@"flags: %d", flags);
       if ((flags & _F_ONEWAY) == 0)
         {
NSLog(@"here setting YES");
           needsResponse = YES;
         }

prints out:
2013-03-09 16:26:14.759 GWorkspace[30760] flags: 1024
2013-03-09 16:26:14.759 GWorkspace[30760] here setting YES

So I tried to figure out where type comes from, so added this
some lines before:

   type = [[inv methodSignature] methodType];
NSLog(@"got type: %d, %c", type, type);

which prints:

2013-03-09 16:26:14.758 GWorkspace[30760] got type: 214276192, `

But the numbers I get here seem to be different when I try it multiple times.
Shouldn't this give me always the same?

No, type is a string and the pointer to that string could be different each time. You should try to print out that string with %s instead of %c. My feeling is that this problem is relate to the other method signature issue you are having. It looks like libobjc2 sometimes comes up with the wrong signature for a selector.

I had a look at the function objc_get_type_qualifiers() in libobjc2:

unsigned objc_get_type_qualifiers (const char *type)
{
        unsigned flags = 0;
#define MAP(chr, bit) case chr: flags |= (1<<bit); break;
        do
        {
                switch (*(type++))
                {
                        default: return flags;
                        MAP('r', 1)
                        MAP('n', 1)
                        MAP('o', 2)
                        MAP('N', 3)
                        MAP('O', 4)
                        MAP('V', 10)
                        MAP('R', 8)
                }
        } while (1);
}

Now these values need to be defined both in the old and the new libobjc the same:

#define _C_CONST        'r'
#define _C_IN           'n'
#define _C_INOUT        'N'
#define _C_OUT          'o'
#define _C_BYCOPY       'O'
#define _C_BYREF        'R'
#define _C_ONEWAY       'V'
#define _C_GCINVISIBLE  '!'

#define _F_CONST        0x01
#define _F_IN           0x01
#define _F_OUT          0x02
#define _F_INOUT        0x03
#define _F_BYCOPY       0x04
#define _F_BYREF        0x08
#define _F_ONEWAY       0x10
#define _F_GCINVISIBLE  0x20

If you would call the libobjc2 function with the string "V" you would expect to get back _F_ONEWAY (0x10), but you will get back 1 << 10 which is 0x400 just like you are getting it. The other values are similarly wrong. It is obvious once you look for it, but the way the function was written, using an inline macro, hides it carefully.

I think the correct solution would be something like this (if we stick to the old coding style):


unsigned objc_get_type_qualifiers (const char *type)
{
        unsigned flags = 0;
#define MAP(chr, bits) case chr: flags |= bits; break;
        do
        {
                switch (*(type++))
                {
                        default: return flags;
                        MAP('r', 0x01)
                        MAP('n', 0x01)
                        MAP('o', 0x02)
                        MAP('N', 0x03)
                        MAP('O', 0x4)
                        MAP('V', 0x10)
                        MAP('R', 0x8)
                }
        } while (1);
}

of course it would be better to use the constants here and to remove the macro, but that could lead to code that people understand. And code that looks like the old version :-(



reply via email to

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