|
From: | Andreas Fink |
Subject: | Re: libobjc2/gnustep-base also failing under FreeBSD + Debian9 |
Date: | Tue, 19 Feb 2019 04:53:16 +0100 |
the cases now gets totally overboard... I have one root class UMObject which does in some cases (debug options) set up a c pointer to the class type's name (this to work around lldb not being able to display stuff at times). Anyhow, today I traced a situation down when the app starts up, initializes my first class, which initializes its superclass which initializes my UMObject root object (which then calls self = [super init] first which calls NSObject init. All good. then it sets up a variable containing flags if certain options are on or not. So every object has a i32bit integer first with the flags. What I saw was that the flags where stored somewhere else in my structure. At the place I have a pointer to another object. So I juggled around the order to see if this can fix the issue by tricking away the optimizer which might reorder things. And then things got totally nuts.... It always breaks somewhere but then a bit later in my code where it assigns the logging object. And the odd thing is I saw my object having property A, B, C and I changed it to B , XA, XC (renamed some) and in the debugger when doing print *self it shows me A, B, C when in the super class and B, XA,XC in the root class. So obviously different parts of the compiler see the objects differently at differnet times and then hell breaks loose. Here is an example.: This is my root object #define UMOBJECT_USE_MAGIC 1 #define UMOBJECT_FLAG_HAS_MAGIC 0x01 #define UMOBJECT_FLAG_LOG_RETAIN_RELEASE 0x02 #define UMOBJECT_FLAG_IS_COPIED 0x04 #define UMOBJECT_FLAG_IS_INITIALIZED 0xCC00 #define UMOBJECT_FLAG_IS_RELEASED 0x3300 @interface UMObject : NSObject { uint32_t _umobject_flags; /*!< internal flags to remember which options this object has */ UMLogFeed *_logFeed; int _ulib_retain_counter; char *_magic; NSString *_xobjectStatisticsName; } @end and this is my current implementation - (UMObject *) init { self=[super init]; if(self) { #ifdef UMOBJECT_USE_MAGIC { const char *str = [[self class] description].UTF8String; size_t len = strlen(str)+1; //_magic = calloc(1,len); /* commented out to see if that helps */ if(_magic) { strncpy(_magic, str, len); _umobject_flags |= UMOBJECT_FLAG_HAS_MAGIC; } } #endif if(alloc_file) { { NSString *s = [NSString stringWithFormat:@"+%@\n",[self objectStatisticsName]]; NSData *d = [s dataUsingEncoding:NSUTF8StringEncoding]; @synchronized(alloc_file) { [alloc_file writeData:d]; } } } /* DEBUG to the console to see what is happening */ printf("self = %p\n",self); printf("_umbobject_flags pos = %p\n",&_umobject_flags); printf("_logFeed pos = %p\n",&_logFeed); _umobject_flags |= UMOBJECT_FLAG_IS_INITIALIZED; printf("_umbobject_flags pos = %p\n",&_umobject_flags); printf("_self = %p\n",self); } return self; } and here is what the debugger says: [root@gnustep-clang7 gitlab]# lldb-6.0 /usr/local/sbin/cnam-server (lldb) target create "/usr/local/sbin/cnam-server" Current executable set to '/usr/local/sbin/cnam-server' (x86_64). (lldb) break set error: invalid combination of options for the given command (lldb) run Process 25406 launched: '/usr/local/sbin/cnam-server' (x86_64) self = 0x1de5318 _umbobject_flags pos = 0x1de5320 *** THEY ARE THE SAME ?!?!?!? _logFeed pos = 0x1de5320 _umbobject_flags pos = 0x1de5320 _self = 0x1de5318 self = 0x1e4dfe8 _umbobject_flags pos = 0x1e4dff0 _logFeed pos = 0x1e4dff0 _umbobject_flags pos = 0x1e4dff0 _self = 0x1e4dfe8 self = 0x1e57648 _umbobject_flags pos = 0x1e57650 _logFeed pos = 0x1e57650 _umbobject_flags pos = 0x1e57650 _self = 0x1e57648 Process 25406 stopped * thread #1, name = 'cnam-server', stop reason = signal SIGSEGV: invalid address (fault address: 0xcc00) frame #0: 0x00007ffff7318dd6 libobjc.so.4.6`objc_release + 22 libobjc.so.4.6`objc_release: -> 0x7ffff7318dd6 <+22>: movq (%rbx), %rcx 0x7ffff7318dd9 <+25>: movq 0x20(%rcx), %rax 0x7ffff7318ddd <+29>: testl $0x4000, %eax ; imm = 0x4000 0x7ffff7318de2 <+34>: jne 0x7ffff7318e5b ; <+155> (lldb) print self error: use of undeclared identifier 'self' (lldb) up frame #1: 0x00007ffff7789bf4 libulib.so.1.9`-[UMObject setLogFeed:](self=0x0000000001de5318, _cmd=">\e", logFeed=0x0000000001e5b938) at UMObject.h:64 61 NSString *_xobjectStatisticsName; 62 } 63 -> 64 @property (readwrite,strong,atomic) UMLogFeed *logFeed; 65 @property (readwrite,assign,atomic) int ulib_retain_counter; 66 67 - (UMObject *) init; it obvioulsy wants to release something which has never been allocated here because the data pointers are not pointing to the same places. (lldb) po self 0x0000000001de5318 (lldb) print *self (UMObject) $1 = { NSObject = { isa = 0x0000000001c6d200 } _umobject_flags = 31832376 <-- invalid value for the flags. this is some kind of pointer... 0x1E5B938 _logFeed = nil _ulib_retain_counter = 0 _magic = 0x0000000000000000 <no value available> _xobjectStatisticsName = nil } (lldb) up frame #2: 0x00007ffff3c7b921 libulibss7config.so.1.9`-[SS7AppDelegate initWithOptions:](self=0x0000000001de5318, _cmd="\xffffff9e\a", options=0x0000000001e48a78) at SS7AppDelegate.m:105 102 ss7_app_delegate = self; 103 _enabledOptions = options; 104 _logHandler = [[UMLogHandler alloc]initWithConsole]; -> 105 self.logFeed = [[UMLogFeed alloc]initWithHandler:_logHandler section:@"main"]; 106 _logLevel = UMLOG_DEBUG; 107 _sctp_dict = [[UMSynchronizedDictionary alloc]init]; 108 _m2pa_dict = [[UMSynchronizedDictionary alloc]init]; (lldb) print *self (SS7AppDelegate) $2 = { UMObject = { NSObject = { isa = 0x0000000001c6d200 } _umobject_flags = 31832376 _logFeed = nil _ulib_retain_counter = 0 _magic = 0x0000000000000000 <no value available> _xobjectStatisticsName = nil } ... This does make absolutely no sense to me and sounds to me like a very severe bug in clang 6 / 7 / 8 in the area of interworking with libobjc2 while accessing properties. Note: the code is compiled with -O0 currently. (except maybe libobjc2 which is compiled with the default) |
[Prev in Thread] | Current Thread | [Next in Thread] |