SIGABRT and SIGV in libobjc2

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

SIGABRT and SIGV in libobjc2

Andreas Fink-2
Hello folks,

I have a heavily multithreaded application which produces two different crashes in libobjc2 code now.
I believe I have hit a race condition.

Here is the firs thread at SIGABRT:


* frame #0: 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602

Thread #27

 lldb) * thread #27: tid = 22581, 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602, name = 'tcap-task-queue'
   frame #0: 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602
  599  {
  600  for (int i=0 ; i<4 ; i++)
  601  {
-> 602  if (0 == ref->ref[i])
  603  {
  604  ref->ref[i] = addr;
  605  *addr = obj;


Thread #26

  * thread #26: tid = 22580, 0x00007fffefd46fcf libc.so.6`gsignal + 207, name = 'tcap-task-queue', stop reason = signal SIGABRT
   frame #0: 0x00007fffefd46fcf libc.so.6`gsignal + 207
   frame #1: 0x00007fffefd483fa libc.so.6`abort + 362
   frame #2: 0x00007fffefd84bd0 libc.so.6`___lldb_unnamed_symbol235$$libc.so.6 + 704
   frame #3: 0x00007fffefd8af96 libc.so.6`___lldb_unnamed_symbol294$$libc.so.6 + 166
   frame #4: 0x00007fffefd8c091 libc.so.6`___lldb_unnamed_symbol299$$libc.so.6 + 2513
   frame #5: 0x00007ffff78c0f49 libgnustep-base.so.1.25`default_free(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 25 at NSZone.m:150
   frame #6: 0x00007ffff78c0d66 libgnustep-base.so.1.25`NSZoneFree(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 54 at NSZone.m:1792
   frame #7: 0x00007ffff77dd5ec libgnustep-base.so.1.25`NSDeallocateObject(anObject=0x00007fff288f7280) + 236 at NSObject.m:705
   frame #8: 0x00007ffff77ddd4c libgnustep-base.so.1.25`-[NSObject dealloc](self=0x00007fff288f7280, _cmd="\x11") + 28 at NSObject.m:1195
   frame #9: 0x00007ffff6f6f7f1 libobjc.so.4.6`release(obj=0x00007fff288f7280) + 225 at arc.m:212
   frame #10: 0x00007ffff6f6fb98 libobjc.so.4.6`objc_release(obj=0x00007fff288f7280) + 40 at arc.m:454

(lldb) up
frame #5: 0x00007ffff78c0f49 libgnustep-base.so.1.25`default_free(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 25 at NSZone.m:150
  147  static void
  148  default_free (NSZone *zone, void *ptr)
  149  {
-> 150    free(ptr);
  151  }
  152
  153  static void
(lldb) up
frame #6: 0x00007ffff78c0d66 libgnustep-base.so.1.25`NSZoneFree(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 54 at NSZone.m:1792
  1789 {
  1790   if (!zone)
  1791     zone = NSDefaultMallocZone();
-> 1792   (zone->free)(zone, ptr);
  1793 }
  1794
  1795 BOOL
(lldb) up
frame #7: 0x00007ffff77dd5ec libgnustep-base.so.1.25`NSDeallocateObject(anObject=0x00007fff288f7280) + 236 at NSObject.m:705
  702        else
  703  {
  704    object_setClass((id)anObject, (Class)(void*)0xdeadface);
-> 705    NSZoneFree(z, o);
  706  }
  707      }
  708    return;
(lldb) up
frame #8: 0x00007ffff77ddd4c libgnustep-base.so.1.25`-[NSObject dealloc](self=0x00007fff288f7280, _cmd="\x11") + 28 at NSObject.m:1195
  1192  */
  1193 - (void) dealloc
  1194 {
-> 1195   NSDeallocateObject (self);
  1196 }
  1197
  1198 - (void) finalize



Also I saw a SIGSEGV crash where it points to a an object at address 0xDEADFB0E. (offset to 0xDEADBEEF?)

Anyone having a hint what I'm seeing here?


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: SIGABRT and SIGV in libobjc2

David Chisnall
On 6 Dec 2017, at 13:46, Andreas Fink <[hidden email]> wrote:

>
> Hello folks,
>
> I have a heavily multithreaded application which produces two different crashes in libobjc2 code now.
> I believe I have hit a race condition.
>
> Here is the firs thread at SIGABRT:
>
>
> * frame #0: 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602
>
> Thread #27
>
>  lldb) * thread #27: tid = 22581, 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602, name = 'tcap-task-queue'
>    frame #0: 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602
>   599 {
>   600 for (int i=0 ; i<4 ; i++)
>   601 {
> -> 602 if (0 == ref->ref[i])
>   603 {
>   604 ref->ref[i] = addr;
>   605 *addr = obj;
>
>
> Thread #26
>
>   * thread #26: tid = 22580, 0x00007fffefd46fcf libc.so.6`gsignal + 207, name = 'tcap-task-queue', stop reason = signal SIGABRT
>    frame #0: 0x00007fffefd46fcf libc.so.6`gsignal + 207
>    frame #1: 0x00007fffefd483fa libc.so.6`abort + 362
>    frame #2: 0x00007fffefd84bd0 libc.so.6`___lldb_unnamed_symbol235$$libc.so.6 + 704
>    frame #3: 0x00007fffefd8af96 libc.so.6`___lldb_unnamed_symbol294$$libc.so.6 + 166
>    frame #4: 0x00007fffefd8c091 libc.so.6`___lldb_unnamed_symbol299$$libc.so.6 + 2513
>    frame #5: 0x00007ffff78c0f49 libgnustep-base.so.1.25`default_free(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 25 at NSZone.m:150
>    frame #6: 0x00007ffff78c0d66 libgnustep-base.so.1.25`NSZoneFree(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 54 at NSZone.m:1792
>    frame #7: 0x00007ffff77dd5ec libgnustep-base.so.1.25`NSDeallocateObject(anObject=0x00007fff288f7280) + 236 at NSObject.m:705
>    frame #8: 0x00007ffff77ddd4c libgnustep-base.so.1.25`-[NSObject dealloc](self=0x00007fff288f7280, _cmd="\x11") + 28 at NSObject.m:1195
>    frame #9: 0x00007ffff6f6f7f1 libobjc.so.4.6`release(obj=0x00007fff288f7280) + 225 at arc.m:212
>    frame #10: 0x00007ffff6f6fb98 libobjc.so.4.6`objc_release(obj=0x00007fff288f7280) + 40 at arc.m:454
>
> (lldb) up
> frame #5: 0x00007ffff78c0f49 libgnustep-base.so.1.25`default_free(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 25 at NSZone.m:150
>   147 static void
>   148 default_free (NSZone *zone, void *ptr)
>   149 {
> -> 150  free(ptr);
>   151 }
>   152
>   153 static void
> (lldb) up
> frame #6: 0x00007ffff78c0d66 libgnustep-base.so.1.25`NSZoneFree(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 54 at NSZone.m:1792
>   1789 {
>   1790  if (!zone)
>   1791    zone = NSDefaultMallocZone();
> -> 1792  (zone->free)(zone, ptr);
>   1793 }
>   1794
>   1795 BOOL
> (lldb) up
> frame #7: 0x00007ffff77dd5ec libgnustep-base.so.1.25`NSDeallocateObject(anObject=0x00007fff288f7280) + 236 at NSObject.m:705
>   702      else
>   703 {
>   704  object_setClass((id)anObject, (Class)(void*)0xdeadface);
> -> 705  NSZoneFree(z, o);
>   706 }
>   707    }
>   708  return;
> (lldb) up
> frame #8: 0x00007ffff77ddd4c libgnustep-base.so.1.25`-[NSObject dealloc](self=0x00007fff288f7280, _cmd="\x11") + 28 at NSObject.m:1195
>   1192 */
>   1193 - (void) dealloc
>   1194 {
> -> 1195  NSDeallocateObject (self);
>   1196 }
>   1197
>   1198 - (void) finalize
>
>
>
> Also I saw a SIGSEGV crash where it points to a an object at address 0xDEADFB0E. (offset to 0xDEADBEEF?)
>
> Anyone having a hint what I'm seeing here?

It looks as if your deallocator is not calling the runtime function that synchronises with weak references.  I don’t know if anyone has ever tested the zombie object stuff with ARC, so it’s probably broken.

David
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: SIGABRT and SIGV in libobjc2

David Chisnall
In reply to this post by Andreas Fink-2
On 6 Dec 2017, at 13:46, Andreas Fink <[hidden email]> wrote:
>
> Also I saw a SIGSEGV crash where it points to a an object at address 0xDEADFB0E. (offset to 0xDEADBEEF?)

This, specifically, looks like you’ve got a use-after-free of the object.  Your quoted line is setting the class to 0xdeadface and something is dereferencing the class pointer.

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: SIGABRT and SIGV in libobjc2

David Chisnall-4
In reply to this post by Andreas Fink-2

> On 6 Dec 2017, at 13:46, Andreas Fink <[hidden email]> wrote:
>
> Hello folks,
>
> I have a heavily multithreaded application which produces two different crashes in libobjc2 code now.
> I believe I have hit a race condition.
>
> Here is the firs thread at SIGABRT:
>
>
> * frame #0: 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602
>
> Thread #27
>
>  lldb) * thread #27: tid = 22581, 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602, name = 'tcap-task-queue'
>    frame #0: 0x00007ffff6f701be libobjc.so.4.6`objc_storeWeak(addr=0x00007fff7be0d628, obj=0x0000000000d32620) + 958 at arc.m:602
>   599 {
>   600 for (int i=0 ; i<4 ; i++)
>   601 {
> -> 602 if (0 == ref->ref[i])
>   603 {
>   604 ref->ref[i] = addr;
>   605 *addr = obj;

This thread is storing a reference to an object 0x0000000000d32620 at address 0x00007fff7be0d628.
It has acquired the weak table lock, and is now modifying the metadata for the weak reference.  It should be safe to dereference ref, because we’ve already done a check that it’s not null, and this table is only modified with the lock held.

> Thread #26
>
>   * thread #26: tid = 22580, 0x00007fffefd46fcf libc.so.6`gsignal + 207, name = 'tcap-task-queue', stop reason = signal SIGABRT
>    frame #0: 0x00007fffefd46fcf libc.so.6`gsignal + 207
>    frame #1: 0x00007fffefd483fa libc.so.6`abort + 362
>    frame #2: 0x00007fffefd84bd0 libc.so.6`___lldb_unnamed_symbol235$$libc.so.6 + 704
>    frame #3: 0x00007fffefd8af96 libc.so.6`___lldb_unnamed_symbol294$$libc.so.6 + 166
>    frame #4: 0x00007fffefd8c091 libc.so.6`___lldb_unnamed_symbol299$$libc.so.6 + 2513
>    frame #5: 0x00007ffff78c0f49 libgnustep-base.so.1.25`default_free(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 25 at NSZone.m:150
>    frame #6: 0x00007ffff78c0d66 libgnustep-base.so.1.25`NSZoneFree(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 54 at NSZone.m:1792
>    frame #7: 0x00007ffff77dd5ec libgnustep-base.so.1.25`NSDeallocateObject(anObject=0x00007fff288f7280) + 236 at NSObject.m:705
>    frame #8: 0x00007ffff77ddd4c libgnustep-base.so.1.25`-[NSObject dealloc](self=0x00007fff288f7280, _cmd="\x11") + 28 at NSObject.m:1195
>    frame #9: 0x00007ffff6f6f7f1 libobjc.so.4.6`release(obj=0x00007fff288f7280) + 225 at arc.m:212
>    frame #10: 0x00007ffff6f6fb98 libobjc.so.4.6`objc_release(obj=0x00007fff288f7280) + 40 at arc.m:454
>
> (lldb) up
> frame #5: 0x00007ffff78c0f49 libgnustep-base.so.1.25`default_free(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 25 at NSZone.m:150
>   147 static void
>   148 default_free (NSZone *zone, void *ptr)
>   149 {
> -> 150  free(ptr);
>   151 }
>   152
>   153 static void
> (lldb) up
> frame #6: 0x00007ffff78c0d66 libgnustep-base.so.1.25`NSZoneFree(zone=0x00007ffff7d7c608, ptr=0x00007fff288f7270) + 54 at NSZone.m:1792
>   1789 {
>   1790  if (!zone)
>   1791    zone = NSDefaultMallocZone();
> -> 1792  (zone->free)(zone, ptr);
>   1793 }
>   1794
>   1795 BOOL
> (lldb) up
> frame #7: 0x00007ffff77dd5ec libgnustep-base.so.1.25`NSDeallocateObject(anObject=0x00007fff288f7280) + 236 at NSObject.m:705
>   702      else
>   703 {
>   704  object_setClass((id)anObject, (Class)(void*)0xdeadface);
> -> 705  NSZoneFree(z, o);
>   706 }
>   707    }
>   708  return;
> (lldb) up
> frame #8: 0x00007ffff77ddd4c libgnustep-base.so.1.25`-[NSObject dealloc](self=0x00007fff288f7280, _cmd="\x11") + 28 at NSObject.m:1195
>   1192 */
>   1193 - (void) dealloc
>   1194 {
> -> 1195  NSDeallocateObject (self);
>   1196 }

The -release method should have called objc_delete_weak_refs, which will have cleared all weak pointers, while holding the lock held.  Weak pointers are materialised only while holding the lock.  

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep