[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>