0

I have several crash reports from an iOS app that stem from a SIGABRT in a free() call.

The call stack is consistent:

0   libsystem_kernel.dylib              0x3863c1f0 __pthread_kill + 8
1   libsystem_c.dylib                   0x385ecfdd abort + 77
2   libsystem_malloc.dylib              0x38664d67 free + 383

I'm trying to get more diagnostics, but in the meantime, did anyone encounter the same? What kind of a wrong argument would crash a free() call? I can see several options:

  • a null pointer (actually legit)
  • a data area pointer (i. e. a string literal)
  • a stack pointer
  • a garbage pointer (i. e. an uninitialized one)
  • a heap pointer that was already freed

Any ideas please? Those are pretty rare, the last one was in Sep '14. But I've got over 10 total, there is probably a bug there.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • Other values will cause problems too, very much any non-NULL pointer not previously returned by `malloc`, `calloc` or `realloc`, or already free'd by `free` or `realloc`. Use valgrind to try and locate the problem. – chqrlie Mar 10 '15 at 20:38
  • It came from user phones, I have no idea how to reproduce it. If I could reproduce, I won't be asking this question :) – Seva Alekseyev Mar 10 '15 at 20:45
  • I would start by going through your code and initialize all C/C++ pointers to 0 (NULL). If you free anything up set the pointer to 0. Check all your code which performs delete (C++) or free(C). Check any arrays you write to to make sure you do not walk over the end. The error is thrown when you try and free() a pointer which does not have an appropriate allocation entry. Most likely an uninitialised pointer or one already freed but not set back to 0 or something has accidentally walking over and corrupting a valid pointer. Since you cannot recreate it, there is not much you can do. – Rory McKinnel Mar 10 '15 at 21:05

1 Answers1

2

If I read the stack dump correctly, the code triggered an assertion in free and called abort. Look at the source code for the libsystem_malloc on http://opensource.apple.com and try and figure which assertion failed.

You have a stray pointer, guessing where it is hiding from a single non reproducible crash is next to impossible. Running your application in the emulator with valgrind (if that's possible) may help you track memory misuse.

It the stack dump is longer that 3 lines, you should have an indication of which call to free caused the problem. It may help you track the bug, but it may also be a late side-effect of some earlier pointer misuse.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Where in the sources could free() be, please? – Seva Alekseyev Mar 10 '15 at 20:55
  • 1
    http://www.opensource.apple.com/source/Libc/Libc-594.1.4/gen/malloc.c is the source for Apple's memory allocator. I'm not sure if is used in iOS. Find the source for `free`, you will see that is calls `abort` if it cannot find the zone for the pointer passed. This narrows the error just a little: it is unlikely to be a pointer already freed, nor a pointer inside a piece of allocated data. – chqrlie Mar 10 '15 at 21:10
  • The `NULL` check is mandated by the C Standard. It is perfectly OK to call `free(NULL)`. Incidentally, it is also OK to `delete` null pointers in C++. – chqrlie Mar 10 '15 at 21:18