[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Topics about GNUstep/libobjc2
From: |
Dr. Rolf Jansen |
Subject: |
Re: Topics about GNUstep/libobjc2 |
Date: |
Tue, 25 Oct 2016 11:47:20 -0200 |
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
Description: Zip archive