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