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 16:52:28 +0100

This should now be fixed:

https://github.com/gnustep/libobjc2/commit/6df23377a02f187e0df8cb359175fb274b34aae1

It turns out that I’d previously got some code that was slightly wrong for this 
and then disabled it…

It needs a lot more testing, but I really should push out the 1.9 release soon 
as there are a load of improvements since the last one.

David

> On 25 Oct 2016, at 15:28, David Chisnall <theraven@sucs.org> wrote:
> 
> 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>
> 
> 
> _______________________________________________
> Discuss-gnustep mailing list
> Discuss-gnustep@gnu.org
> https://lists.gnu.org/mailman/listinfo/discuss-gnustep




reply via email to

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