Python
macos
gdb

macOS Sierraにpython3.6.3のソースコードを読むための環境を構築

More than 1 year has passed since last update.

pythonのソースコードを読むにあたりMacOSに環境を構築しました。その時のメモになります。Xcodeはインストールされていることが前提です。

Pythonのダウンロード

適当なディレクトリを作成してそこにPythonの公式サイトからtgzファイルを持ってきます。

$ curl https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tgz -O

Pythonのインストール

取得したtgzファイルを解凍して,生成されたディレクトリに移動します。

$ tar -xf Python-3.6.3.tgz
$ cd Python-3.6.3

./configure --with-pydebugを実行すると…コケました。

$ ./configure --with-pydebug

...

Agreeing to the Xcode/iOS license requires admin privileges, please run “sudo xcodebuild -license” and then retry this command.

checking for gcc... gcc
checking whether the C compiler works... no
configure: error: in `/Users/XXX/Python-3.6.3':
configure: error: C compiler cannot create executables
See `config.log' for more details

Xcodeのライセンスに合意する必要があるようです。表示されたコマンドをそのまま実行します。

sudo xcodebuild -license

条項が最後まで表示された後,agreeと入力すると完了します。これで,./configureが通ります。

$ ./configure --with-pydebug

makeを実行します。

$ make

ビルドは成功しますが,下記のメッセージが表示されsqlite3,sslが利用できません。

Python build finished successfully!
The necessary bits to build these optional modules were not found:
_dbm                  _sqlite3              _ssl               
nis                   ossaudiodev           spwd               
zlib                                                           
To find the necessary bits, look in setup.py in detect_modules() for the module's name.

The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:
atexit                pwd                   time  
$

Python Developer's Guide次のコマンドを参考に次のコマンドを実行にしました。

$ xcode-select --install
$ brew install openssl xz

makeで生成したファイルを削除するため,make distcleanを実行して,再ビルドします。

$ make distclean
$ CPPFLAGS="-I$(brew --prefix openssl)/include" \
  LDFLAGS="-L$(brew --prefix openssl)/lib" \
  ./configure --with-pydebug
$ make

...

Python build finished successfully!
The necessary bits to build these optional modules were not found:
ossaudiodev           spwd                                     
To find the necessary bits, look in setup.py in detect_modules() for the module's name.

The following modules found by detect_modules() in setup.py, have been
built by the Makefile instead, as configured by the Setup files:
atexit                pwd                   time        
$

…まだいくつか解消されないものが表示されますが,次に進みます。

gdbの環境整備

gdbのバージョンが古いとエラーがデバッグができないことがあります。homebrewで最新版にしましょう。

$ brew uninstall gdb; brew install gdb

さきほど作成したpythongdbで実行してみます。

$ gdb python.exe
GNU gdb (GDB) 8.0.1

...

Reading symbols from python.exe...done.
(gdb) b builtin_dir
Breakpoint 1 at 0x1001d8414: file Python/bltinmodule.c, line 790.
(gdb) r
Starting program: /Users/XXXX/Python-3.6.3/python.exe 
Unable to find Mach task port for process-id 52003: (os/kern) failure (0x5).
 (please check gdb is codesigned - see taskgated(8))
(gdb) 

コード署名が必要なようなので,こちらを参考に署名します。下記は実施後です。

$ gdb python.exe
GNU gdb (GDB) 8.0.1

...

Reading symbols from python.exe...done.
(gdb) b builtin_dir
Breakpoint 1 at 0x1001d8414: file Python/bltinmodule.c, line 790.
(gdb) r
Starting program: /Users/XXXX/Python-3.6.3/python.exe 
During startup program terminated with signal ?, Unknown signal.

上記のとおり,実際にデバックを実行してもエラーになってしまいます。このエラーを解消するため,下記のコマンドを実行します。

$ echo "set startup-with-shell off" >> ~/.gdbinit

これで,ブレークポイントを設定した場所で実行が停止できるようになりました。

$ gdb python.exe
GNU gdb (GDB) 8.0.1

...

Reading symbols from python.exe...done.
(gdb) b main
Breakpoint 1 at 0x10000158d: file ./Programs/python.c, line 28.
(gdb) r
Starting program: /Users/XXX/Python-3.6.3/python.exe 
[New Thread 0x1403 of process 739]
warning: unhandled dyld version (15)

Thread 2 hit Breakpoint 1, main (argc=1, argv=0x7fff5fbffa88) at ./Programs/python.c:28
28      (void)_PyMem_SetupAllocators("malloc");
(gdb)