discuss-gnustep
[Top][All Lists]
Advanced

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

Re: Topics about GNUstep/libobjc2


From: David Chisnall
Subject: Re: Topics about GNUstep/libobjc2
Date: Tue, 25 Oct 2016 15:28:53 +0100

Hi,

It would help if the reduced test case compiled, but adding -march=native seems 
to fix that.  It would also help if it were something a bit more minimal, but 
from what you’ve sent me:

The crash happens in [CalcFactor evaluate], which simply returns the ResultType 
ivar itsValue.  Clang is emitting sse instructions for this, assuming that the 
ivar is correctly 128-bit aligned.  The offset is 48, so it is aligned within 
the object, but the 64-bit header makes it unaligned again.

Here is a reduced test case that demonstrates the problem:

#include <objc/runtime.h>
#include <stdint.h>
#include <assert.h>
typedef int v4si __attribute__ ((vector_size (16)));
@interface Foo
{
        Class isa;
        v4si var;
}
- (void)check;
+ (id)new;
@end
@implementation Foo
+ (id)new
{
        return class_createInstance(self, 0);
}
- (void)check
{
        size_t addr = (size_t)&var;
        assert(addr & 15 == 0);
}
@end

int main(void)
{
        [[Foo new] check];
}

It appears that we’re not taking the offset into account correctly.  I thought 
I’d fixed this, but apparently I haven’t.  I’ll take a look now.

David

> On 25 Oct 2016, at 14:47, Dr. Rolf Jansen <rj@obsigna.com> wrote:
> 
> Hi David,
> 
> Attached to this message you will find a .zip-Archive with the stripped down 
> test case. It contains a FreeBSD Makefile and a .xcodeproj-package.
> 
> It should build on FreeBSD against libobjc2 (ports) and Mac OS X (native 
> libobjs) out of the box. On Mac OS X it should run fine and it would crash on 
> FreeBSD.
> 
> If you uncomment the #pragma pack() directives in CalcObject.h it builds and 
> runs fine also on FreeBSD 11-RELEASE-p1.
> 
> Best regards
> 
> Rolf
> 
>> Am 25.10.2016 um 06:55 schrieb David Chisnall <theraven@sucs.org>:
>> 
>> Hi Rolf,
>> 
>> From your code snippets, it looks as if it should work and you’ve probably 
>> found either a compiler or runtime bug.  If you can put together a reduced 
>> test case (ideally something that doesn’t depend on anything other than 
>> libobjc) I’ll take a look.
>> 
>> David
>> 
>>> On 24 Oct 2016, at 23:38, Dr. Rolf Jansen <rj@obsigna.com> wrote:
>>> 
>>> Hi David,
>>> 
>>> many thanks for the reply.
>>> 
>>> Does this mean, that it is not advised to use arbitrary C structs as 
>>> Objective-C instance variables?
>>> 
>>> The code is more than 10 years old, and at that time I started learning 
>>> Objective-C, and I heavily intermixed C data structures and algorithms into 
>>> a hollow OOP construct. It is a calculator engine with more than 10000 
>>> lines of code.
>>> 
>>> The code (without #pragma pack, and -O1,-O2,-O3, or -Ofast) crashes 
>>> consistently on FreeBSD when accessing one instance variable indicated 
>>> below from within the respective object.
>>> 
>>> ...
>>> 
>>> typedef struct
>>> {
>>>   ErrorFlags   flag;
>>>   unsigned     begin, count;
>>>   char        *field;
>>> } ErrorRecord;
>>> 
>>> typedef struct ResultType
>>> {
>>>   ResultTypeFlags     f;
>>>   unsigned            n;
>>>   boolean             b;
>>>   long long           i;
>>>   long double         r;
>>>   long double complex z;
>>>   struct ResultType  *v;
>>>   char               *s;
>>>   ErrorRecord         e;
>>> } ResultType;
>>> 
>>> @interface CalcObject : MyObject
>>> {
>>>   boolean     isPercent;
>>>   TokenPtr    itsToken;
>>>   Precedence  itsPrecedence;
>>>   OpKind      itsOpKind;
>>>   CalcObject *itsParent;
>>>   Calculator *itsCalculator;
>>> }
>>> 
>>> ...
>>> - many instance methods;
>>> ...
>>> 
>>> @end
>>> 
>>> 
>>> @interface CalcFactor : CalcObject
>>> {
>>>   ResultType itsValue;    <<<<<<<<<<<< accessing this one gives Bus Error
>>> }
>>> 
>>> ...
>>> - some more instance methods;
>>> ...
>>> 
>>> @end
>>> 
>>> 
>>> Questions:
>>> 
>>> As said already, on Mac OS X this code does not crash with Apple's 
>>> non-fragile ABI. Is this only by coincidence and other similar constructs 
>>> may crash? Or, may I continue to use my 10000 line of code, without a major 
>>> rewrite?
>>> 
>>> Likewise on FreeBSD, is it safe to rely on the magic of #pragma pack(8) or 
>>> is my code too fragil for the non-fragil ABI?
>>> 
>>> AFAIK, 8 byte struct packing/padding is standard for 64bit architectures 
>>> and 4 byte packing/padding for 32bit architectures. Isn't it possible to do 
>>> this reliable for C structs included as Objective-C instance variables?
>>> 
>>> Best regards
>>> 
>>> Rolf
>>> 
>>>> Am 24.10.2016 um 17:09 schrieb David Chisnall 
>>>> <David.Chisnall@cl.cam.ac.uk>:
>>>> 
>>>> Hi Rolf,
>>>> 
>>>> With the non-fragile ABI, it isn’t safe to assume that classes have the 
>>>> same layout as C structs.  This works with the fragile ABI, because the 
>>>> compiler is entirely responsible for layout there.  It sounds as if 
>>>> #pragma pack is removing some padding that the ABI mandates for C structs, 
>>>> but which the Objective-C runtime is not adding.
>>>> 
>>>> David
>>>> 
>>>>> On 24 Oct 2016, at 17:52, Dr. Rolf Jansen <rj@obsigna.com> wrote:
>>>>> 
>>>>> Would it be OK to discuss on this list topics about Objective-C 
>>>>> development involving clang + GNUstep/libobjc2, but almost nothing else 
>>>>> from GNUstep?
>>>>> 
>>>>> I constructed my own root class having only the bare basic methods that 
>>>>> are needed by a quite old project, that I revamped for inclusion into a 
>>>>> new plain C project. My class/code is working well on FreeBSD 11.0 
>>>>> RELEASE-p1 (amd64) when compiled with clang 3.8 (system) with -O0 or -Os 
>>>>> and linked against libobjc2 1.8.1 (ports). Once compiled with any other 
>>>>> optimization mode, it crashes (Bus Error) when accessing a certain 
>>>>> instance variable struct.
>>>>> 
>>>>> It is working well on Mac OS X 11.12 when compiled in any -O mode with my 
>>>>> root class and linked against the native ObjC runtime. It is almost 
>>>>> always working on FreeBSD 11 in any -O mode when using NSObject as the 
>>>>> root class and linked against libobjc2 1.8.1 and gnustep-base (ports), 
>>>>> although, I saw 2 random crashes.
>>>>> 
>>>>> After some debugging I found a workaround. Once I add a #pragma pack(8) 
>>>>> directive at the top of the headers that declare my class hierarchy + all 
>>>>> the C structs that are used throughout, the code with my root class works 
>>>>> well on FreeBSD 11 when compiled in any -O mode -- a pack(4) does work as 
>>>>> well.
>>>>> 
>>>>> It is still possible that something is wrong with my code. However, after 
>>>>> these many experiments, I tend to assume that the Objective-C runtime and 
>>>>> the compiler sometimes disagree on correct packing/alignment of instance 
>>>>> variables in instantiated objects. I can't tell, though, if the runtime 
>>>>> or the compiler is responsible for this.
>>>>> 
>>>>> In the case that it is appropriate to discuss this further on this list, 
>>>>> I am ready to send more information. If this is not the appropriate list, 
>>>>> then please may I ask for advise on which location this topic may be 
>>>>> discussed.
>>>>> 
>>>>> The #pragma pack(8) does neither cost anything nor is it a very ugly 
>>>>> hack, so perhaps, it isn't even worth to discuss this issue furthermore, 
>>>>> given that clang 4.0 may be out soon.
>>>>> 
>>>>> Best regards
>>>>> 
>>>>> Rolf
> 
> <BareObjC.zip>




reply via email to

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