discuss-gnustep
[Top][All Lists]
Advanced

[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

Attachment: BareObjC.zip
Description: Zip archive


reply via email to

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