2

I have a Python C extension I am debugging in Xcode 5.1.1 on Mavericks which causes Xcode to crash as soon as the tests are run as described here .

I am then prompted to reinstall Xcode as it is apparently corrupted.

The crash log contains:

Crashed Thread:  14  Dispatch queue: DBGLLDBLauncher Serial Queue

Exception Type:  EXC_BAD_ACCESS (Code Signature Invalid)
Exception Codes: 0x0000000000000032, 0x00000001128b9000

kernel messages:
-1 sec              CODE SIGNING: cs_invalid_page(0x1128b9000): p=6382[Xcode] final status 0x1000200, denying page sending SIGKILL
-1 sec              CODE SIGNING: process 6382[Xcode]: rejecting invalid page at address 0x1128b9000 from offset 0x1000 in file "/Users/dwhitla/.virtualenvs/lrparser/bin/python" (cs_mtime:1404897136.0 == mtime:1404897136.0) (signed:1 validated:1 tainted:1 wpmapped:0 slid:0)
-2 sec              CODE SIGNING: cs_invalid_page(0x101443000): p=6766[python] final status 0x0, allowing (remove VALID) page
-6 sec              CODE SIGNING: cs_invalid_page(0x1000): p=6760[GoogleSoftwareUp] final status 0x0, allowing (remove VALID) page
-15 sec             CODE SIGNING: cs_invalid_page(0x10af5c000): p=6757[python] final status 0x0, allowing (remove VALID) page
Community
  • 1
  • 1
Dave
  • 764
  • 7
  • 17

1 Answers1

1

The issue is that mkvirtualenv copies your system python executable (in this case /usr/bin/python) into the virtual environment. What it doesn't then do is code-sign the executable. In Xcode on 10.9 (possibly earlier) this fails a code-signing validation step which expects the signing date and last modification date to be identical.

That this crashes Xcode, and the poor advice in the resulting pop-up are other problems which Apple should probably address.

Your options are to either code-sign the copied $VIRTUAL_ENV/.Python dylib and $VIRTUAL_ENV/bin/python wrapper with your own valid code-signing identity (assuming you have one), or you can patch /Library/Python//site-packages using my attached patch against virtualenv-1.11.6. This patch works for me but I recommend backing up your current virtualenv.py before using it yourself:

--- virtualenv.py.orig  2014-08-11 11:55:55.000000000 +1000
+++ virtualenv.py.new   2014-08-12 14:24:29.000000000 +1000
@@ -1348,38 +1348,21 @@
         if 'EPD' in prefix:
             logger.debug('EPD framework detected')
             original_python = os.path.join(prefix, 'bin/python')
-        shutil.copy(original_python, py_executable)
+        shutil.copy2(original_python, py_executable)

         # Copy the framework's dylib into the virtual
         # environment
-        virtual_lib = os.path.join(home_dir, '.Python')
+        virtual_lib = os.path.join(home_dir, 'Python')

         if os.path.exists(virtual_lib):
             os.unlink(virtual_lib)
         copyfile(
             os.path.join(prefix, 'Python'),
             virtual_lib,
-            symlink)
-
-        # And then change the install_name of the copied python executable
-        try:
-            mach_o_change(py_executable,
-                          os.path.join(prefix, 'Python'),
-                          '@executable_path/../.Python')
-        except:
-            e = sys.exc_info()[1]
-            logger.warn("Could not call mach_o_change: %s. "
-                        "Trying to call install_name_tool instead." % e)
-            try:
-                call_subprocess(
-                    ["install_name_tool", "-change",
-                     os.path.join(prefix, 'Python'),
-                     '@executable_path/../.Python',
-                     py_executable])
-            except:
-                logger.fatal("Could not call install_name_tool -- you must "
-                             "have Apple's development tools installed")
-                raise
+            False)
+        os.symlink(os.path.dirname(prefix), os.path.join(home_dir, 'Versions'))
+        os.symlink(os.path.join('Versions', 'Current', 'Resources'),
+                   os.path.join(home_dir, 'Resources'))

     if not is_win:
         # Ensure that 'python', 'pythonX' and 'pythonX.Y' all exist
Dave
  • 764
  • 7
  • 17
  • The edits to the script didn't work for me, but your advice is spot on: after signing the .Python and python files, Xcode behaved itself – dvj Aug 21 '14 at 17:33
  • Being a patch, its application is entirely dependent upon which version of the virtualenv module you have currently installed. Do you know which path through the code was taken in your case? I have only tested the non-EPD path because it is the only one which applies to my use case. – Dave Aug 29 '14 at 02:45