linux环境下服务器程序的查看与gdb调试

前言

这一篇主要是记录下调试服务器程序常用的命令,内容很简单,但是长时间不用很容易记混,因为游戏服务器也不是天天宕机,所以当有一天突然挂掉需要调试的时候,如果记不清调试命令很容易耽误时间,有好几次我就把gdb gameserver core记成了gdb core gameserver,所以干脆把这些内容统计到一起,查询的时候也方便。

查询程序的运行情况

  • ps aux
    命令是常用来查询程序进程运行情况的,基本上不会漏掉,但是显示的无关程序太多,看着不方便所以常配合grep过滤

  • ps aux | grep gameserver
    可以显示指定过滤内容的程序,但是这种显示方式没有标题,对于不熟悉的人来说看不太明白,就像下面这样

    1
    2
    3
    $ps aux | grep init
    root 1 0.0 0.0 19232 976 ? Ss 2018 0:01 /sbin/init
    510 2042 0.0 0.0 105492 932 pts/2 S+ 10:04 0:00 grep init

    所以这里给出ps aux默认的输出格式:
    USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
    其中STAT: 该行程的状态,linux的进程常见状态:
    D 不可中断 uninterruptible sleep (usually IO)
    R 运行 runnable (on run queue)
    S 中断 sleeping
    T 停止 traced or stopped
    Z 僵死 a defunct or zombie process
    注: 其它状态还包括W(无驻留页), <(高优先级进程), N(低优先级进程), L(内存锁页).

  • ps -eo pid,lstart,etime,command | grep gameserver
    有时需要查询特定进程的指定信息,比如运行时间,那么可以通过-o选项来指定,显示信息很明确

    1
    2
    15499 Thu Jan 10 23:22:53 2019    11:24:12 ./gameserver -d
    18097 Fri Jan 11 10:47:04 2019 00:01 grep gameserver

杀死指定进程

  • killall -10 gameserver: 按照进程名杀死进程,-10为自定义杀死信号
  • kill -10 gameserver_pid: 按照进程ID杀死进程,-10为自定义杀死信号

  • kill -9 gameserver_pid: -9为强制杀死进程的信号,无法被捕捉

  • kill -6 gameserver_pid: -6可以杀死进程并产生core文件

gdb调试

通常要想使用gdb调试需要在编译程序时加上-g选项,之后才能用gdb进行调试:gcc -g main.c -o gameserver,如果想在程序崩溃时产生core文件,还需要设置系统命令ulimit -c unlimited才可以,调试程序又分为直接启动调试、调试core文件和附加到正在运行的进程调试,每种方式的参数略有不同:

  1. 直接启动调试,gdb gameserver
    这种方式相当于直接通过gdb启动了程序,并开启了调试模式,所以是拉取了新的进程

  2. 调试core文件,gdb gameserver core.xxx
    这种方式相当于展示程序崩溃前的堆栈情况,并进行调试,所以也算是拉取了新的进程

  3. 附加进程调试,gdb attach gameserver_pid/gdb gameserver gameserver_pid
    这种方式是将gdb调试工具附加到程序运行的当前进程上,并没有拉取新的进程,操作上也可以先敲gdb回车,然后再attach gameserver_pid,不过这种情况对于其他用户启动的程序,通常会提示“ptrace: 不允许的操作.”,所以需要使用sudo运行gdb

gdb常用命令

以下命令为调试linux程序常用的gdb命令,都是在调试服务器程序core文件过程中不断积累的,还有一些高级命令一般很少用到,掌握下面这些基本上就可以应付很多场景了,其中打印信息的命令print在打印map、vector等显示不友好,可以参考gdb调试脚本中的内容。

  • run/r:重新开始运行文件
  • break/b: 设置断点(I. b filename:linenum, II. b functioname, 条件断点: b position if condition)
  • info/i: 查看信息(I. i b:查看断点信息,i locals: 查看当前帧局部变量值,i threads: 查看线程)
  • delete/d: 删除断点(delete 3:删除通过info breakpoints查到的第3个断点,其实还可以删除别的)
  • list/l: 查看原代码(list -n:显示第n行前后的源代码。list 函数名:查看具体函数)
  • next/n: 逐过程调试(类似于VS的F10)
  • step/s: 逐语句调试(类似于VS的F11)
  • frame/f:切换函数的栈帧(可以调试输出指定函数内的情况)
  • print/p:打印值及地址(用来显示变量值)
  • thread/t: 切换线程(调试指定线程,用来处理多线程程序)
  • continue/c:继续运行(常用调试完断点之后)
  • backtrace/bt:显示堆栈(可以查看函数的调用的栈帧和层级关系)
  • source: 加载脚本(可以在调试过程中使用脚本完成复杂逻辑调试)
Albert Shi wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客