23 October 2017

环境说明

在本机,用的是 Mac 和 clion,每次开机都会开启一个 linux fedora 的虚拟机

php 和 swoole 都是在 linux 虚拟机里面编译运行的
Mac 上用 clion 的 remote gdb debug 功能来调试 linux 的 php 扩展程序

linux 配置

编译 php 和 swoole

➜ cd path/to/php-7.1.9/
➜ ./configure --disable-all --enable-debug
➜ make -j8 && make install
➜ cd path/to/swoole-src/
➜ phpize
➜ ./configure --enable-swoole-debug --enable-debug
➜ make -j8 && make install

➜ php -i | grep php.ini
Configuration File (php.ini) Path => /usr/local/lib
Loaded Configuration File => /usr/local/lib/php.ini

➜  echo "extension=swoole.so" >> /usr/local/lib/php.ini
➜ php -m
[PHP Modules]
Core
date
pcre
Reflection
SPL
standard
swoole

开启 gdbserver

➜ dnf install -y gdbserver
➜ gdbserver :6666 /usr/local/bin/php /path/to/server.php

配置 clion

➜ ln -s /usr/local/Cellar/php71/7.1.11_22/ /usr/local/php
➜ vi CMakeLists.txt
# 修改 include
INCLUDE_DIRECTORIES(BEFORE ./include ./ /usr/local/php/include /usr/local/php/include/php /usr/local/php/include/php/Zend /usr/local/php/include/php/main)

在 project 下,右键整个项目,设置 Mark Directory as "Project Sources and Headers"

mac 配置

编译 linux gdb

➜ git clone git://sourceware.org/git/binutils-gdb.git
➜ ./configure --target=x86_64-linux-gnu --with-python --prefix=<install_dir>
➜ make -j8 && make install

clion 连接

开始调试

在 linux 开启监听 6666 端口

➜ gdbserver :6666 /usr/local/bin/php ./server.php

在 clion 上就可以设置断点 debug 了

调试 fork

➜ vi ~/.gdbinit
set follow-fork-mode child
set detach-on-fork off
set follow-exec-mode new

调试 fork 的程序有点困难,目前有个麻烦的解决方案是:

  1. 首先执行 server.php

    ➜ /usr/local/bin/php ./server.php
    
  2. 调试主进程

    ➜ gdbserver :6666 --attach `ps -C php | sed '1d' | head -n 1 | awk '{print $1}'`
    
  3. 在 clion 上开启 debug

调试线程报错

用 clion 调试线程的时候,会报错 Child terminated with signal = 0x5 (SIGTRAP) thread
重新安装 gdb 和 gdbserver https://sourceware.org/gdb/wiki/BuildingCrossGDBandGDBserver

在 mac 端

➜ tar xf binutils-gdb-gdb-8.0.1-release.tar.gz
➜ cd binutils-gdb-gdb-8.0.1
➜ ./configure CC=/usr/bin/gcc CXX=/usr/bin/g++ --target=x86_64-linux-gnu --prefix=/PATH/TO/INSTALL/linux-gdb8
➜ make && make install

在 linux 端

➜ tar xf binutils-gdb-gdb-8.0.1-release.tar.gz
➜ cd binutils-gdb-gdb-8.0.1
➜ gdb/gdbserver/
➜ ./configure --prefix=/usr/local/gdbserver --host=x86_64-linux-gnu
➜ make && make install
➜ /usr/local/gdbserver/bin/gdbserver :6666 --attach PID

Program received signal SIGTRAP, Trace/breakpoint trap

The other possibility i can think of is:
1.Your process is running more than one thread.
For eg - 2 say x & y.
2.Thread y hits the break point but you have attached gdb to thread x.
This case is a Trace/breakpoint trap.

意思是:线程所打断点的地方,主线程也会在该地方停下(解决的方法是删除主线程可能会停下来的断点)