Bug 20981 - Dynamic library debugging on MacOS X 10.12 (Sierra) and dyld 15 is broken
Summary: Dynamic library debugging on MacOS X 10.12 (Sierra) and dyld 15 is broken
Status: UNCONFIRMED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-12-18 05:23 UTC by Stefan Budeanu
Modified: 2018-03-17 12:02 UTC (History)
11 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Budeanu 2016-12-18 05:23:56 UTC
I am running Mac OS X 10.12.2 (Sierra) and I've noticed gdb's support for debugging dynamic libraries is broken. The following message is printed on startup:

"warning: unhandled dyld version (15)"

It appears the latest dyld on MacOS Sierra has undergone major changes and the version was bumped from 14 to 15. (https://opensource.apple.com/source/dyld/dyld-421.2/) 

Last time a version bump happened the fix was to simply modify the DYLD_VERSION_MAX define (see https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=d4ccb5e05c99c4006fe43ab08ebe13b7a74fc111).

I tried doing this and was met with a new error:

"Cannot insert breakpoint -1
Cannot access memory at address 0xe85d"

The address 0xe85d is the offset of the "gdb_image_notifier" function in the /usr/lib/dyld executable (see https://opensource.apple.com/source/dyld/dyld-421.2/src/dyld_gdb.cpp.auto.html).

It appears Apple has changed something fundamental about how dyld is built and/or loaded (possibly related to PIE/ASLR), here are before and after examples:

Mac OS X 10.11.6:

otool -l /usr/lib/dyld 
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777223          3  0x00           7    14       1696 0x00000085
Load command 0
      cmd LC_SEGMENT_64
  cmdsize 552
  segname __TEXT
   vmaddr 0x00007fff5fc00000
   vmsize 0x0000000000038000
  fileoff 0
 filesize 229376
  maxprot 0x00000007
 initprot 0x00000005
   nsects 6
    flags 0x0

Mac OS X 10.12.2:

otool -l /usr/lib/dyld
/usr/lib/dyld:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777223          3  0x00           7    14       1696 0x00000085
Load command 0
      cmd LC_SEGMENT_64
  cmdsize 552
  segname __TEXT
   vmaddr 0x0000000000000000
   vmsize 0x000000000003e000
  fileoff 0
 filesize 253952
  maxprot 0x00000007
 initprot 0x00000005
   nsects 6
    flags 0x0

Notice that vmaddr is now 0x0. I wrote a hack to add the base address of the TEXT segment of dyld to the notifier address and this gets gdb to start successfully: https://github.com/stefanmb/binutils-gdb/commit/ee5bfeff7174f6e0b515f87d8ba2214ce45a02aa

With the patch "info shared" appears to work correctly.

I am now encountering further issues related to shared libraries and forking (children are seeing SIGSEGV after my patch), but I have not had a chance to investigate further. I will update this issue if I find more relevant info.

This behaviour reproduces on the latest gdb (7.12.50.20161217-git).

Does anyone know what has to be done to fix this issue properly?

I am available to test potential fixes, but I require some support to resolve this problem properly.

Thank you very much for your help!
Comment 1 Stefan Budeanu 2016-12-21 20:42:15 UTC
It turns out the fork crashing issues may be due to the children having software breakpoints left over after fork. I get a similar problem with lldb, and disassembling the core dump shows `INT 3` instructions being inserted in gdb_image_notifier. I think that is a separate problem (though also annoying).

The hack I linked to got gdb starting but I've run into a new problem setting breakpoints in my library because the location of my functions seem to also be read as offsets instead of the relocated addresses. This issue only seems to happen for certain object files and the raw offsets are being read directly from the DWARF2 info as far as I can tell.
Comment 2 Joe 2017-05-06 15:51:23 UTC
In my case, the gdb is starting the original program successfully, but 

gdb) info shared

does not show any information. Also, the break points that I had set in the shared library are not detected and the execution does not stop there.
Comment 3 Shahzeb 2017-05-15 03:09:24 UTC
Any update on this?

I've uninstalled and then installed gdb twice (via brew). I've also codesigned it. Still get "No shared libraries loaded at this time.". Really frustrating.

macOS: 10.12.4
Comment 4 Chris Friedt 2017-09-26 23:05:37 UTC
I'm also encountering this on 10.12.6 ... sigh..
Comment 5 EvanT 2017-10-25 02:32:22 UTC
This also occurs on Mac OS X 10.13 (High Sierra)
Comment 6 Shahzeb 2017-10-25 04:30:59 UTC
This problem still isn't resolved, but I came up with a solution: Simply run a docker container I've built which has GDB within it. Instructions on my github: https://github.com/shahzeb1/cpp-gdb-docker-image
Comment 7 Andy Law 2017-10-27 12:27:14 UTC
Gdb 8.0.1 doesn't have this problem as I see. However, the dynamic library still can't debug at all. It can't collect debug symbols...
Comment 8 Chris Friedt 2017-12-05 00:47:10 UTC
#sadface :(
Comment 9 Pedro Alves 2017-12-05 11:55:45 UTC
The simple hard fact is that unfortunately the macOS/Darwin port isn't really getting much attention.  Most gdb devs tend to run/focus on GNU/Linux.
We need someone motivated to actually dig in to the sources, study the issue in detail, and fix the issue.  Who knows, maybe end up becoming port maintainer.  :-)

This could be you!
Comment 10 ben convey 2018-03-17 12:02:11 UTC
same issue on high sierra ( 10.13.2 ) :(