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 <[email protected]> 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 <[email protected]> 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 <[email protected]>: >>> >>> 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 <[email protected]> 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 >>>>> <[email protected]>: >>>>> >>>>> 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 <[email protected]> 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 > [email protected] > https://lists.gnu.org/mailman/listinfo/discuss-gnustep _______________________________________________ Discuss-gnustep mailing list [email protected] https://lists.gnu.org/mailman/listinfo/discuss-gnustep
