Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable macOS build #23

Merged
merged 6 commits into from
Jul 8, 2020
Merged

Enable macOS build #23

merged 6 commits into from
Jul 8, 2020

Conversation

phil-blain
Copy link
Contributor

@phil-blain phil-blain commented May 26, 2020

Checklist

  • Used a fork of the feedstock to propose changes
  • Bumped the build number (if the version is unchanged)
  • Re-rendered with the latest conda-smithy (Use the phrase @conda-forge-admin, please rerender in a comment in this PR for automated rerendering)
  • Ensured the license file is being packaged.

Closes #7

TODO:


13/06/2020: here is a final description of this PR, now that all tests are passing.

Add support for building GDB on macOS

On macOS, debuggers need to be codesigned with a codesigning certificate located in the System keychain to be able to control other processes.

The script recipe/macos-codesign/macos-setup-codesign.sh sets up this certificate. It is taken from the LLDB repository and only slightly modified to use "gdb_codesign" as the certificate name. Using a script seems more robust than the manual method mentioned in the GDB wiki.
This script requires 'sudo', so it is run automatically on the CI but not in a user installation. It is copied to the installation prefix so that users can run it after installing GDB.

The script recipe/macos-codesign/macos-codesign-gdb.sh actually calls macos-setup-codesign.sh and then signs the GDB executable using the just created certificate.

A post-link script runs the recipe/macos-codesign/macos-codesign-gdb.sh if passwordless sudo is available (in the CI), and if it's not, it writes to $PREFIX/.messages.txt such that users are notified that they need to sign GDB in order to use it, using the provided script.
Note: at the moment, conda mangles multi-line messages in $PREFIX/.messages.txt (conda/conda#8809 ). This bug was fixed in conda/conda#9841, which is already merged, and so should appear in conda 4.8.4. Maybe we want to wait for this conda release before merging this ? It would make for a nicer end-user experience, but since this message is also shown upon environment activation (as long as GDB is not codesigned), I think it's ok.

The message shown also informs users how to avoid being prompted for a password every login when they start an executable in GDB.

An activate script is also added to make sure that GDB is correctly codesigned upon environment activation. If it's not codesigned, users are instructed to run the provided script (by showing the same message as the post-link script).

Here is a copy of the message users will see when installing (with the fix in conda/conda#9841 applied to conda) :

Preparing transaction: done
Verifying transaction: done
Executing transaction: \ 

Codesigning GDB
---------------
Due to macOS security restrictions, the GDB executable 
needs to be codesigned to be able to control other processes.

The codesigning process requires the Command Line Tools
(or a full XCode installation). 
To install the Command Line Tools, run

  xcode-select --install

The codesigning process also requires administrative permissions
(your user must be able to run `sudo`).

To codesign GDB, simply run the included script:

  macos-codesign-gdb.sh

and enter your password. 

Make sure this environment, "<environment name>", is activated
so that "macos-codesign-gdb.sh" is found in your $PATH.

For more information, see: https://sourceware.org/gdb/wiki/PermissionsDarwin

Avoiding being prompted for a password
--------------------------------------
On recent macOS versions, you will be prompted for an administrator username and password
the first time you `run` an executable in GDB in each login session.

To instead be prompted for your own password,
you can add your user to the '_developer' group:

  sudo dscl . merge /Groups/_developer GroupMembership <username>

To avoid being prompted for any password, run

  sudo security authorizationdb write system.privilege.taskport allow


Showing this message again
--------------------------
Once GDB is codesigned, this message will disappear.
To show this message again, run

  macos-show-caveats.sh

done
#
# To activate this environment, use
#
#     $ conda activate gdb
#
# To deactivate an active environment, use
#
#     $ conda deactivate

Since the Python executable from the conda-forge python package does not include debugging symbols on macOS (see 3,4), we skip the test for the GDB "libpython" integration and add a simple "Hello World" C program, just to test that the debugger can actually run a program.

We use Travis CI for the macOS build since the conda-forge Travis macOS image use macOS 10.13 ('xcode9.4'). When tested under Azure and Travis under macOS 10.14 and 10.15, the build phase succeeds but when running the executable in GDB, GDB hangs. Doing manual testing on 10.15.5 I can replicate this behaviour about half the time I run an executable in GDB, so it looks like a race condition.

This is probably due to an intermittent GDB bug. The bug reporter suggests a patch that makes GDB not hang, but fails to launch the executable instead (again, about half the time it still works correctly). I've added this patch to the recipe and added a mention of that in $PREFIX/.messages.txt to inform users to just try again if they hit this bug:

Intermittent GDB error on Mojave and later
------------------------------------------
We've detected you are running macOS Mojave or later. GDB has a known intermittent bug on
recent macOS versions, see: https://sourceware.org/bugzilla/show_bug.cgi?id=24069

If you receive the following error when running your executable in GDB:

  During startup program terminated with signal ?, Unknown signal

simply try to `run` your executable again, it should work eventually.

We also add a README in the recipe dir to warn maintainers and contributors that it's possible that the automated testing starts failing when the Travis CI macOS 10.13 image is decommissioned (by Travis or conda-forge).

@conda-forge-linter
Copy link

Hi! This is the friendly automated conda-forge-linting service.

I just wanted to let you know that I linted all conda-recipes in your PR (recipe) and found it was in an excellent condition.

I do have some suggestions for making it better though...

For recipe:

  • License is not an SPDX identifier (or a custom LicenseRef) nor an SPDX license expression.

@phil-blain
Copy link
Contributor Author

phil-blain commented May 26, 2020

Note: building GDB 8.3.1 (from the gdb tarball) succeeds on my machine (10.11). It also builds fine under a conda environment (conda create -n compiler compiler; conda activate compilers).

However I can reproduce the build failure locally using conda build:

$ conda build --dirty -m .ci_support/osx_python3.6.____cpython.yaml recipe
[...] # skipping lots of stuff
Configuring in ./gdb
/Applications/Xcode.app/Contents/Developer/usr/bin/make  all-recursive
Making all in .
/bin/sh ./libtool  --tag=CC   --mode=compile x86_64-apple-darwin13.4.0-clang -DHAVE_CONFIG_H -I.  -I. -I. -I../bfd -I./../include -I./../bfd  -I./../intl -D_FORTIFY_SOURCE=2 -mmacosx-version-min=10.9 -isystem $PREFIX/include -I$PREFIX/include -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Wshadow -march=core2 -mtune=haswell -mssse3 -ftree-vectorize -fPIC -fPIE -fstack-protector-strong -O2 -pipe -isystem $PREFIX/include -fdebug-prefix-map=$SRC_DIR=/usr/local/src/conda/gdb-8.3.1 -fdebug-prefix-map=$PREFIX=/usr/local/src/conda-prefix -MT dis-buf.lo -MD -MP -MF .deps/dis-buf.Tpo -c -o dis-buf.lo dis-buf.c
[...] # skipping until the first invocation of `CXX`
  CXX    ada-exp.o
In file included from ada-exp.y:38:
In file included from ./defs.h:28:
In file included from ./common/common-defs.h:77:
In file included from build-gnulib/import/stdlib.h:36:
In file included from /Users/Philippe/Logiciels/miniconda3/conda-bld/gdb_1590587843385/_build_env/bin/../include/c++/v1/stdlib.h:100:
In file included from build-gnulib/import/math.h:27:
In file included from /Users/Philippe/Logiciels/miniconda3/conda-bld/gdb_1590587843385/_build_env/bin/../include/c++/v1/math.h:311:
In file included from /Users/Philippe/Logiciels/miniconda3/conda-bld/gdb_1590587843385/_build_env/bin/../include/c++/v1/type_traits:417:
In file included from /Users/Philippe/Logiciels/miniconda3/conda-bld/gdb_1590587843385/_build_env/bin/../include/c++/v1/cstddef:37:
./../intl/version:1:1: error: unknown type name 'GNU'
GNU gettext library from gettext-0.12.1
^
./../intl/version:1:12: error: expected ';' after top level declarator
GNU gettext library from gettext-0.12.1

So the problem is that the file ./intl/VERSION in the GDB tarball gets included instead of the file /Users/Philippe/Logiciels/miniconda3/conda-bld/gdb_1590587843385/_build_env/bin/../include/c++/v1/version, probably because of the -I./../intl flag that gets added by the GNU build system.

A simple fix would be to add a patch that renames this file to VERSION.txt

@phil-blain
Copy link
Contributor Author

phil-blain commented May 27, 2020

Update: it appears conda-build does not handle patches that are just renaming a file (created with git mv; git commit, git format-patch.

Renaming the file in build.sh makes the build succeeds.

New problem: the code signing does not work in the conda-build environment because the compiler package activation script sets CODESIGN_ALLOCATE:

$ cd /Users/Philippe/Logiciels/miniconda3/conda-bld/gdb_1590596079611/work
$ source build_env_setup.sh 
$ env |grep CODESIGN
CODESIGN_ALLOCATE=/Users/Philippe/Logiciels/miniconda3/conda-bld/gdb_1590596079611/_build_env/bin/x86_64-apple-darwin13.4.0-codesign_allocate

unseting this variable makes the code signing work.

@phil-blain
Copy link
Contributor Author

Build succeeds, but the executable must be signed for the test phase of conda-build to work (since the package is installed to a new location).

@jakirkham
Copy link
Member

How do you know it is about signing? Test failure suggests it is picking up the wrong (maybe system?) Python.

Unable to locate python frame
+ [[ 36 != \2\7 ]]

@phil-blain
Copy link
Contributor Author

Possibly that's another error.
https://dev.azure.com/conda-forge/feedstock-builds/_build/results?buildId=167940&view=logs&j=9c5ef928-2cd6-52e5-dbe6-9d173a7d951b&t=20c71c51-4b27-578b-485d-06ade2de1d00&l=5538 says:

Unable to find Mach task port for process-id 53609: (os/kern) failure (0x5).
(please check gdb is codesigned - see taskgated(8))

which is the message I get on my mac when my GDB is not signed.

@jakirkham
Copy link
Member

@phil-blain
Copy link
Contributor Author

Thanks @jakirkham. The up-to-date info is actually in the GDB wiki, which I link to in the PR description:

The + [[ 36 != \2\7 ]] is caused by the run_test.sh script using set -ex so all lines are of the script are outputed, it's not an error.

@phil-blain phil-blain force-pushed the add-macos branch 2 times, most recently from d753745 to 277cf33 Compare May 29, 2020 16:14
@isuruf
Copy link
Member

isuruf commented May 29, 2020

If you are signing this with a certificate in the CI build, how is this going to work in a user environment?

@phil-blain
Copy link
Contributor Author

phil-blain commented May 29, 2020

@isuruf the user will have to run the included script to generate a self-signed certificate and sign the binary. This is what Homebrew does.

@phil-blain
Copy link
Contributor Author

phil-blain commented May 31, 2020

Currently run_test.sh hangs when invoking gdb on macOS on azure.
I built the package locally on my 10.11 system and the debugger seems to work well. I published it under phil-blain/label/test.

I tried installing the package and using gdb on another mac running 10.13 and it also works well, however when logged into this mac using SSH from my 10.11 machine and invoking gdb, a graphical authentication pop up appears on the 10.13 system. When prefixing gdb with sudo, it works through SSH.

On azure it appears even prefixing with sudo makes it hang.

Interestingly, I tried installing and testing the package on Travis CI with this configuration:

language: cpp
os: osx

osx_image:
- xcode11.5 # 10.15
- xcode11.3 # 10.14
- xcode10.1 # 10.13
- xcode9.2  # 10.12
- xcode8    # 10.11

install: 
# Download miniconda
- "wget https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -O ~/miniconda.sh"
# Install miniconda
- "bash ~/miniconda.sh -b -p $HOME/miniconda"

script:
# Create "gdb" conda environment
- "source $HOME/miniconda/bin/activate"
- "conda config --add channels conda-forge"
- "conda config --set channel_priority strict"
- "conda create -y -c phil-blain/label/test -n gdb gdb"
- "conda activate gdb"
# check codesigning
- "security find-certificate -c gdb_codesign"
- "security dump-trust-settings -d"
- "type gdb"
- "gdb --version"
- "codesign -vv $(which gdb)"
- "codesign -d --entitlements - $(which gdb)"
# check GDB
- "echo 'set startup-with-shell off' >> ~/.gdbinit"
- "g++ -g hello.cpp -o hello"
- "sudo gdb -batch -ex r --args hello"

and this succeeds on 10.11-10.13 but fails on 10.14 and 10.15. When SSH-ing into the VM (travis debug mode), it works if I prefix gdb with sudo.

@phil-blain
Copy link
Contributor Author

A small update: I switched the provider to Travis for macOS, and added this before calling GDB in the run_test.sh script:

if [[ $(uname) == "Darwin" ]]; then
  sudo /usr/sbin/DevToolsSecurity -enable
  sudo security authorizationdb write system.privilege.taskport allow
fi

which seems to help: with this GDB does not hang.

The Travis image used by conda-forge is the xcode9.4 one (macOS 10.13), and so it's definitely something with the macOS version that makes GDB hang, since as far as I was able to check the Azure VM is under 10.14.

Next step: Now that GDB does not hang, we can see if we can actually run the test script. Locally on my Mac, I get this:

$ gdb --args python testing/process_to_debug.py 
GNU gdb (GDB) 8.3.1
# --- >8 ---
Reading symbols from python...

warning: `/tmp/lto.o': can't open to read symbols: No such file or directory.
(No debugging symbols found in python)
(gdb) r
Starting program: /Users/Philippe/Logiciels/miniconda3/envs/gdb/bin/python testing/process_to_debug.py
[New Thread 0x1103 of process 75303]
warning: `/tmp/lto.o': can't open to read symbols: No such file or directory.

Program received signal SIGSEGV, Segmentation fault.
0x00007fff8a68b8ea in ?? () from /usr/lib/system/libsystem_kernel.dylib
(gdb) py-bt
Traceback (most recent call first):
  PyCFunction invocation (unable to read func_obj: missing debuginfos?)
  (unable to read python frame information)

So it seems that some debug information is missing from the Python binary to be able to use the CPython "libpython.py" GDB extension.

On Linux, the test works, so I'm guessing the conda-forge python package has debug symbols on Linux but not on macOS... @jakirkham @isuruf is that possible ? I know nothing at all about the Python build process..

@phil-blain
Copy link
Contributor Author

Seems to be related to the Python build using link time optimization with -g, seems to work with GCC but not Clang...

@jakirkham
Copy link
Member

Thanks for bringing up this point about codesigning. Have raised issue ( conda-forge/conda-forge.github.io#1081 ) to discuss how we should handle this in general.

@jakirkham
Copy link
Member

Good point about the debug symbols on macOS. I think we should skip that test on macOS for now as fixing the python package's debug symbols would be a different issue. If you have a moment, could you please file an issue about it (if there isn't already one). Do we already have a test with a basic C program that works on macOS with gdb? If so, that might be enough.

Thanks for sticking with this! I know these are quite hairy issues, but it seems like we are quite close here. Looking forward to seeing gdb on macOS 😄

@phil-blain
Copy link
Contributor Author

@jakirkham I understand now why GDB complains about /tmp/lto.o, I'll add some details later tonight. I agree that we could simply run GDB on a simple C program and skip the Python test in a first iteration.

@isuruf
Copy link
Member

isuruf commented Jun 11, 2020

Does lldb package on conda-forge work with python?

@phil-blain
Copy link
Contributor Author

Allright so this is what I found out.

  • on macOS, the full debug info is never stored in the executable. It is either left in the object files, and the executable just keeps a record of the paths to the object files, or it is put into a "dSYM bundle".
  • when compiling and linking in a single step with the clang/clang++ drivers and the -g flag, i.e.
    clang -o app -g main.cpp Matrix.cpp Vector.cpp cholesky.cpp ...
    
    the driver automatically calls dsymutil at the end of the process to create this dSYM bundle. (this can be seen by adding -v to tell the driver to output all commands it issues.)
  • when compiling and linking in separate steps, which is usually the case with Make- or Automake- based build systems, the driver does not call dsymutil, so the debug info is left in the object files.
  • When compiling and linking in a single step with -flto, the driver calls the linker with the -object_path_lto flag and a path in $TMPDIR, eg. -object_path_lto /var/folders/lr/r6n2057j0dzd4gdb614fp0740000gp/T/cc-ac0bf8.o.
  • when compiling and linking in separate steps, the driver does not add this option to the linker call.
  • man ld reveals that if object_path_lto is not used, the linker deletes the temporary file used for link time optimization after the linking step is finished.

The last point means that the final executable keeps a reference to this deleted temporary file (I guess /tmp/lto.o is hardcoded in ld64's source code, I did not check that). So when the executable is loaded in GDB, the debugger tries to load the debugging symbols from the now deleted temporary file.

Adding -Wl,object_path_lto,lto.o to the linking command (in a Makefile for example) leaves the object file used for link time optimization (here lto.o) in the build directory, which allows to debug the executable. It also allows calling dsymutil manually to create the dSYM bundle.

References:


Of course having debug symbols distributed with a conda-forge package would have to be discussed on each package's feedstock. It would mean telling the build system of each package to add the flag -Wl,object_path_lto,lto.o, adding a call to dsymutil in build.sh, and copying the dSYM bundle to the recipe prefix.

For now as said above I'll just add a test with a simple C program.

@phil-blain
Copy link
Contributor Author

@isuruf about LLDB: the conda-forge lldb recipe uses LLDB_USE_SYSTEM_DEBUGSERVER=ON on macOS:
https://github.com/conda-forge/lldb-feedstock/blob/131e70d7e90d3fac9a45111ce82342a31e83efa6/recipe/build.sh#L8-L13,

which I guess was done to avoid having to codesign the executable. I haven't been able to use the conda-forge lldb at all. For a simple "hello-world"-type program, I get:

$ conda create -n lldb lldb
$ conda activate lldb
$ lldb hello
(lldb) target create "hello"
Current executable set to '/path/to/hello' (x86_64).
(lldb) r
error: process launch failed: failed to get reply to handshake packet

This seems to be related to inability for the lldb executable to connect with the system debugserver (which on my system is at /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/debugserver and is not in PATH and can't be found by xcrun --find debugserver)...

phil-blain added a commit to phil-blain/gdb-feedstock that referenced this pull request Jun 27, 2020
Add support for building GDB on macOS.

On macOS, debuggers need to be codesigned with a codesigning certificate
located in the System keychain to be able to control other processes.

The script `recipe/macos-codesign/macos-setup-codesign.sh` sets up this
certificate. It is taken from the LLDB repository [1] and only slightly
modified to use "gdb_codesign" as the certificate name. Using a script
seems more robust than the manual method mentioned in the GDB wiki [2].
This script requires 'sudo', so it is run automatically on the CI but
not in a user installation. It is copied to the installation prefix
so that users can run it after installing GDB.

The script `recipe/macos-codesign/macos-codesign-gdb.sh` actually calls
'macos-setup-codesign.sh' and then signs the GDB executable using the
just created certificate.

A post-link script runs the
`recipe/macos-codesign/macos-codesign-gdb.sh` is passwordless sudo is
available (in the CI), and if it's not, it writes to
$PREFIX/.messages.txt such that users are notified that they need to
sign GDB in order to use it, using the provided script.

An activate script is also added to make sure that GDB is correctly
codesigned upon environment activation. If it's not codesigned, users
are instructed to run the provided script.

Since the Python executable from the conda-forge python package does not
include debugging symbols on macOS (see [3],[4]), we skip the test for
the GDB "libpython" integration and add a simple "Hello World" C
program, just to test that the debugger can actually run a program.

We use Travis CI for the macOS build since the conda-forge Travis macOS
image use macOS 10.13 ('xcode9.4') [5]. When tested under Azure and
Travis under macOS 10.14 and 10.15, the build
phase succeeds but when running the executable in GDB, GDB hangs.
This is probably due to system security settings that need tweaking (I'm
suspecting a graphical authentification popup since that's what I
witnessed during local testing).

We also add a README in the recipe dir to warn maintainers and contributors that
it's possible that the automated testing starts failing when the Travis
CI macOS 10.13 image is decomissioned (by Travis or conda-forge).

[1]: https://github.com/llvm/llvm-project/blob/master/lldb/scripts/macos-setup-codesign.sh
[2]: https://sourceware.org/gdb/wiki/PermissionsDarwin
[3]: conda-forge#23
[4]: conda-forge/python-feedstock#354
[5]: https://docs.travis-ci.com/user/reference/osx/
@conda-forge-linter
Copy link

Hi! This is the friendly automated conda-forge-linting service.

I was trying to look for recipes to lint for you, but it appears we have a merge conflict.
Please try to merge or rebase with the base branch to resolve this conflict.

Please ping the 'conda-forge/core' team (using the @ notation in a comment) if you believe this is a bug.

phil-blain added a commit to phil-blain/gdb-feedstock that referenced this pull request Jun 27, 2020
Add support for building GDB on macOS.

On macOS, debuggers need to be codesigned with a codesigning certificate
located in the System keychain to be able to control other processes.

The script `recipe/macos-codesign/macos-setup-codesign.sh` sets up this
certificate. It is taken from the LLDB repository [1] and only slightly
modified to use "gdb_codesign" as the certificate name. Using a script
seems more robust than the manual method mentioned in the GDB wiki [2].
This script requires 'sudo', so it is run automatically on the CI but
not in a user installation. It is copied to the installation prefix
so that users can run it after installing GDB.

The script `recipe/macos-codesign/macos-codesign-gdb.sh` actually calls
'macos-setup-codesign.sh' and then signs the GDB executable using the
just created certificate.

A post-link script runs the
`recipe/macos-codesign/macos-codesign-gdb.sh` is passwordless sudo is
available (in the CI), and if it's not, it writes to
$PREFIX/.messages.txt such that users are notified that they need to
sign GDB in order to use it, using the provided script.

An activate script is also added to make sure that GDB is correctly
codesigned upon environment activation. If it's not codesigned, users
are instructed to run the provided script.

Since the Python executable from the conda-forge python package does not
include debugging symbols on macOS (see [3],[4]), we skip the test for
the GDB "libpython" integration and add a simple "Hello World" C
program, just to test that the debugger can actually run a program.

We use Travis CI for the macOS build since the conda-forge Travis macOS
image use macOS 10.13 ('xcode9.4') [5]. When tested under Azure and
Travis under macOS 10.14 and 10.15, the build
phase succeeds but when running the executable in GDB, GDB hangs.
This is probably a manifestation of an intermittent GDB bug [6].
We use the patch provided in the bug report to mitigate the effects
of that bug.

We also add a README in the recipe dir to warn maintainers and contributors that
it's possible that the automated testing starts failing when the Travis
CI macOS 10.13 image is decomissioned (by Travis or conda-forge).

[1]: https://github.com/llvm/llvm-project/blob/master/lldb/scripts/macos-setup-codesign.sh
[2]: https://sourceware.org/gdb/wiki/PermissionsDarwin
[3]: conda-forge#23
[4]: conda-forge/python-feedstock#354
[5]: https://docs.travis-ci.com/user/reference/osx/
[6]: https://sourceware.org/bugzilla/show_bug.cgi?id=24069
@conda-forge-linter
Copy link

Hi! This is the friendly automated conda-forge-linting service.

I just wanted to let you know that I linted all conda-recipes in your PR (recipe) and found it was in an excellent condition.

@phil-blain phil-blain mentioned this pull request Jun 27, 2020
Merged
5 tasks
phil-blain added a commit to phil-blain/gdb-feedstock that referenced this pull request Jun 27, 2020
Add support for building GDB on macOS.

On macOS, debuggers need to be codesigned with a codesigning certificate
located in the System keychain to be able to control other processes.

The script `recipe/macos-codesign/macos-setup-codesign.sh` sets up this
certificate. It is taken from the LLDB repository [1] and only slightly
modified to use "gdb_codesign" as the certificate name. Using a script
seems more robust than the manual method mentioned in the GDB wiki [2].
This script requires 'sudo', so it is run automatically on the CI but
not in a user installation. It is copied to the installation prefix
so that users can run it after installing GDB.

The script `recipe/macos-codesign/macos-codesign-gdb.sh` actually calls
'macos-setup-codesign.sh' and then signs the GDB executable using the
just created certificate.

A post-link script runs the
`recipe/macos-codesign/macos-codesign-gdb.sh` is passwordless sudo is
available (in the CI), and if it's not, it writes to
$PREFIX/.messages.txt such that users are notified that they need to
sign GDB in order to use it, using the provided script.

An activate script is also added to make sure that GDB is correctly
codesigned upon environment activation. If it's not codesigned, users
are instructed to run the provided script.

Since the Python executable from the conda-forge python package does not
include debugging symbols on macOS (see [3],[4]), we skip the test for
the GDB "libpython" integration and add a simple "Hello World" C
program, just to test that the debugger can actually run a program.
We also re-introduce the Python test on Linux, which was deleted in
conda-forge#27.

We use Travis CI for the macOS build since the conda-forge Travis macOS
image use macOS 10.13 ('xcode9.4') [5]. When tested under Azure and
Travis under macOS 10.14 and 10.15, the build
phase succeeds but when running the executable in GDB, GDB hangs.
This is probably a manifestation of an intermittent GDB bug [6].
We use the patch provided in the bug report to mitigate the effects
of that bug.

We also add a README in the recipe dir to warn maintainers and contributors that
it's possible that the automated testing starts failing when the Travis
CI macOS 10.13 image is decomissioned (by Travis or conda-forge).

[1]: https://github.com/llvm/llvm-project/blob/master/lldb/scripts/macos-setup-codesign.sh
[2]: https://sourceware.org/gdb/wiki/PermissionsDarwin
[3]: conda-forge#23
[4]: conda-forge/python-feedstock#354
[5]: https://docs.travis-ci.com/user/reference/osx/
[6]: https://sourceware.org/bugzilla/show_bug.cgi?id=24069
@phil-blain
Copy link
Contributor Author

@isuruf @jakirkham it seems that the build is running both on travis-ci.org (continuous-integration/travis-ci/pr) and travis-ci.com (Travis CI - Pull Request).. is this expected ?

@phil-blain phil-blain mentioned this pull request Jun 27, 2020
5 tasks
phil-blain added a commit to phil-blain/gdb-feedstock that referenced this pull request Jun 27, 2020
Add support for building GDB on macOS.

On macOS, debuggers need to be codesigned with a codesigning certificate
located in the System keychain to be able to control other processes.

The script `recipe/macos-codesign/macos-setup-codesign.sh` sets up this
certificate. It is taken from the LLDB repository [1] and only slightly
modified to use "gdb_codesign" as the certificate name. Using a script
seems more robust than the manual method mentioned in the GDB wiki [2].
This script requires 'sudo', so it is run automatically on the CI but
not in a user installation. It is copied to the installation prefix
so that users can run it after installing GDB.

The script `recipe/macos-codesign/macos-codesign-gdb.sh` actually calls
'macos-setup-codesign.sh' and then signs the GDB executable using the
just created certificate.

A post-link script runs the
`recipe/macos-codesign/macos-codesign-gdb.sh` is passwordless sudo is
available (in the CI), and if it's not, it writes to
$PREFIX/.messages.txt such that users are notified that they need to
sign GDB in order to use it, using the provided script.

An activate script is also added to make sure that GDB is correctly
codesigned upon environment activation. If it's not codesigned, users
are instructed to run the provided script.

Since the Python executable from the conda-forge python package does not
include debugging symbols on macOS (see [3],[4]), we skip the test for
the GDB "libpython" integration and add a simple "Hello World" C
program, just to test that the debugger can actually run a program.

We use Travis CI for the macOS build since the conda-forge Travis macOS
image use macOS 10.13 ('xcode9.4') [5]. When tested under Azure and
Travis under macOS 10.14 and 10.15, the build
phase succeeds but when running the executable in GDB, GDB hangs.
This is probably a manifestation of an intermittent GDB bug [6].
We use the patch provided in the bug report to mitigate the effects
of that bug.

We also add a README in the recipe dir to warn maintainers and contributors that
it's possible that the automated testing starts failing when the Travis
CI macOS 10.13 image is decomissioned (by Travis or conda-forge).

[1]: https://github.com/llvm/llvm-project/blob/master/lldb/scripts/macos-setup-codesign.sh
[2]: https://sourceware.org/gdb/wiki/PermissionsDarwin
[3]: conda-forge#23
[4]: conda-forge/python-feedstock#354
[5]: https://docs.travis-ci.com/user/reference/osx/
[6]: https://sourceware.org/bugzilla/show_bug.cgi?id=24069
@phil-blain
Copy link
Contributor Author

@gqmelo @marcelotrevisani @isuruf @jakirkham

This PR is now ready for review. I've updated the PR description with a detailed description, as well as an example of how it will look for users when installing the package.

Copy link
Contributor

@gqmelo gqmelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the OSX bits, but in general it looks good to me. Great work!

I just commented on a duplicate flag when running configure, but I'll leave up to you if you want to remove it now.

recipe/build.sh Outdated Show resolved Hide resolved
Add support for building GDB on macOS.

On macOS, debuggers need to be codesigned with a codesigning certificate
located in the System keychain to be able to control other processes.

The script `recipe/macos-codesign/macos-setup-codesign.sh` sets up this
certificate. It is taken from the LLDB repository [1] and only slightly
modified to use "gdb_codesign" as the certificate name. Using a script
seems more robust than the manual method mentioned in the GDB wiki [2].
This script requires 'sudo', so it is run automatically on the CI but
not in a user installation. It is copied to the installation prefix
so that users can run it after installing GDB.

The script `recipe/macos-codesign/macos-codesign-gdb.sh` actually calls
'macos-setup-codesign.sh' and then signs the GDB executable using the
just created certificate.

A post-link script runs the
`recipe/macos-codesign/macos-codesign-gdb.sh` is passwordless sudo is
available (in the CI), and if it's not, it writes to
$PREFIX/.messages.txt such that users are notified that they need to
sign GDB in order to use it, using the provided script.

An activate script is also added to make sure that GDB is correctly
codesigned upon environment activation. If it's not codesigned, users
are instructed to run the provided script.

Since the Python executable from the conda-forge python package does not
include debugging symbols on macOS (see [3],[4]), we skip the test for
the GDB "libpython" integration and add a simple "Hello World" C
program, just to test that the debugger can actually run a program.

We use Travis CI for the macOS build since the conda-forge Travis macOS
image use macOS 10.13 ('xcode9.4') [5]. When tested under Azure and
Travis under macOS 10.14 and 10.15, the build
phase succeeds but when running the executable in GDB, GDB hangs.
This is probably a manifestation of an intermittent GDB bug [6].
We use the patch provided in the bug report to mitigate the effects
of that bug.

We also add a README in the recipe dir to warn maintainers and contributors that
it's possible that the automated testing starts failing when the Travis
CI macOS 10.13 image is decomissioned (by Travis or conda-forge).

[1]: https://github.com/llvm/llvm-project/blob/master/lldb/scripts/macos-setup-codesign.sh
[2]: https://sourceware.org/gdb/wiki/PermissionsDarwin
[3]: conda-forge#23
[4]: conda-forge/python-feedstock#354
[5]: https://docs.travis-ci.com/user/reference/osx/
[6]: https://sourceware.org/bugzilla/show_bug.cgi?id=24069
Remove the logic for Python 2.7, for which this package is not
built anymore.
The GDB tarball contains both GPLv2 and GPLv3 at the root level,
but this tarball also contains related libraries needed to build GDB.
The code for the debugger itself is in the `gdb/` subdirectory,
and this folder contains only the GPLv3 in `COPYING`.

Update the license path and use the correct SPDX license identifier.
- Add titles
- Show how to avoid being prompted for a password
- Warn about https://sourceware.org/bugzilla/show_bug.cgi?id=24069 on
  Mojave and later
- Change recipe/README.md to mention that bug.
@phil-blain
Copy link
Contributor Author

The package can be tested by downloading from the conda-forge testing label:

conda create -n gdb -c conda-forge/label/testing gdb

@phil-blain
Copy link
Contributor Author

@isuruf @jakirkham I'll merge this in a day or two, if you want to take a look (no worry if you don't have time).

@phil-blain phil-blain merged commit 4df33c4 into conda-forge:master Jul 8, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Building on macOS
6 participants