[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: libobjc2/gnustep-base also failing under FreeBSD + Debian9

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_IS_COPIED             0x04
#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;

and this is my current implementation

- (UMObject *) init
    self=[super init];
            const char *str = [[self class] description].UTF8String;
            size_t len = strlen(str)+1;
            //_magic = calloc(1,len); /* commented out to see if that helps */
                strncpy(_magic, str, len);
                _umobject_flags  |= UMOBJECT_FLAG_HAS_MAGIC;
                NSString *s = [NSString stringWithFormat:@"address@hidden",[self objectStatisticsName]];
                NSData *d = [s dataUsingEncoding:NSUTF8StringEncoding];
                    [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:

address@hidden 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
->  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   }
-> 64   @property (readwrite,strong,atomic) UMLogFeed *logFeed;
   65   @property (readwrite,assign,atomic) int ulib_retain_counter;
   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

(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)

reply via email to

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