用gdb调试游戏服务端

标签: gdb 调试 游戏 | 发表时间:2014-11-17 00:15 | 作者:a374826954
出处:http://blog.csdn.net

前言

说说gdb的重要性

一般来说,提到gdb,都是用命令来调试。“命令”,这个对于用户来说几乎等同于繁杂的词语。尽管事实确实如此,但实际的开发调试必须用到gdb。现在,大多数Linux系统是存在于服务器当中。我们想操作这些系统时,一般是通过Terminal来操作。也就是说这些Linux系统不具有图形界面。而调试一般分两部分,开发时调试和运行时调试。当我们的程序部署到Linux上时,那就需要忘记那该死图形调试器了。

说说写这篇文章的目的

昨天公司游戏的其中服务端崩溃了。我在调试时忘记了gdb命令-_-!(当然最后我是找出这个Bug了)。因此写这篇博文加深记忆,同时分享一下经验。


基础命令

注:gdb远不止这么少的命令
1. attach: 用gdb调试一个正在运行中的进程
gdb <program> PID 或 gdb attach PID

2. br: 设置断点
br filename:line_num

br namespace::classname::func_name

3. n: 单步跳过   s: 单步进入

4. finish:执行到函数retun返回

5. list: 列出当前位置之后的10行代码;list line_number: 列出line_number之后的十行代码

6. bt(backtrace):列出调用栈(同类型的还有where,经验告诉我,当你想列出堆栈信息时,而发现没有效果,最好两个命令都试试)

7. info locals:列出当前函数的局部变量

8. p var_:打印变量值

9. info breakpoints:列出所有断点

10. delete breakpoints:删除所有断点;delete breakpoints id:删除编号为id的断点;disable/enable breakpoints id:禁用/启用断点

11. break ... if ... 条件中断

下面我主要讲述的是运行时调试。

测试代码

#include <stdio.h>

void Crash()
{
    int *a;
    *a = 1;
    printf("%d\n", *a);
}

void EndlessLoop()
{
    int i = 1;
    int j = 0;
    while (i)
    {
        ++j;
    }
}

int main()
{
    Crash();			// 崩溃
    EndlessLoop();		// 死循环
    return 0;
}


调试崩溃

http://blog.csdn.net/yitouhan/article/details/17175113 这是我之前写的一篇关于防止崩溃的文章。
这里用到core文件:
在一个程序崩溃时,它一般会在指定目录下生成一个core文件。core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的。
这个core的文件名一般是core.PID,即core.3745等等

我一般会在/etc/security/limits.conf(Centos)设置Linux对core的支持,这需要重启系统,之后就会永久支持打印core文件。
添加下面命令
*               soft    core            unlimited
*               hard    core            unlimited
意思是软件和硬件都打印core文件,而且是unlimited(无限制)。这里可以将unlimited替换成指定的大小。
注:还有其它的一些设置方式,可以自行上网搜索查询。

就在此时,服务端test崩溃了。在我的工作目录中发现了core.1234这个文件(core文件默认输出到工作目录)。

输入gdb test core.1234进入gdb调试。
这时再输入where查看堆栈信息,如下图:


看到这些信息,不要告诉我还找不到出错的地方吧?!

调试死循环

当我们发现死循环的时候不要中止进程。假设进程ID是1234
输入命令 gdb attach 1234
你会发现gdb会断点在死循环的地方,也许可能不是很清楚,你可以一直输入n。注意行号,你会发现这就是出现死循环的地方。
再输入where,来查看堆栈信息,如下图所示。


看到这些信息,不要告诉我还找不到出错的地方吧?!

半死循环

半死循环(这是我自己用的一个名词,不知道其它教程等是否有使用)就是在运行的时候出错,导致循环了几百万次、几千万次甚至几亿次的一种Bug。
虽然这种Bug相对于崩溃和死循环的危害性相对小一些,但是调试起来就难很多。如果你有对这种Bug有更好的调试经验,希望您可以分享一下!




作者:a374826954 发表于2014-11-17 0:15:00 原文链接
阅读:119 评论:0 查看评论

相关 [gdb 调试 游戏] 推荐:

用gdb调试游戏服务端

- - CSDN博客编程语言推荐文章
一般来说,提到gdb,都是用命令来调试. “命令”,这个对于用户来说几乎等同于繁杂的词语. 尽管事实确实如此,但实际的开发调试必须用到gdb. 现在,大多数Linux系统是存在于服务器当中. 我们想操作这些系统时,一般是通过Terminal来操作. 也就是说这些Linux系统不具有图形界面. 而调试一般分两部分,开发时调试和运行时调试.

gdb调试工具

- - CSDN博客系统运维推荐文章
查看帮助一是man 命令,二是进入 www.gnu.org,找到gdb的帮助文档(更详细). gcc -Wall -g main.c -o main,只有这样才能产生调试信息,包括core的调试信息.     run(r)  运行,执行到断点,重新用r,表示重新开始执行.     list(l)  列出源代码,l 2,l main,l 2,16(数字表示行数).

Linux下gdb调试

- - CSDN博客移动开发推荐文章
关于gdb的其他客套话不多说,直接进入正题. 列出产生执行文件源代码的一部分. 执行一行源代码但不进入函数内部. 执行一行源代码而且进入函数内部. 监视一个变量的值,一旦值有变化程序停住. 1.新建一个源文件vi yrp.cc,源代码如下:. 2.生成可执行文件 g++ -g -o yrp yrp.cc  注意必须使用-g参数,编译会加入调试信息,否则无法调试执行文件..

[转]GDB调试多线程

- - 小彰
GDB 多线程调试基本命令 实现简介 以及一个问题的解决. 一直对GDB多线程调试接触不多,最近因为工作有了一些接触,简单作点记录吧. 先介绍一下GDB多线程调试的基本命令. 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID. 切换当前调试的线程为指定ID的线程.

Linux下进行GDB调试

- - CSDN博客推荐文章
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具. 一般来说,GDB主要帮助自己完成下面四个方面的功能;. 1:启动你的程序,可以按照你的自定义的要求随心所欲的运行程序. 2:可以让被调试的程序在你所指定的调制的断点处停住(断点可以是条件表达式). 3:当程序被停住时,可以检查你的程序中发生的事.

GDB学习之道:GDB调试精粹及使用实例

- - CSDN博客系统运维推荐文章
要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(<和>)和外壳通配符(*、. 如果你使用不带参数的run命令,gdb就再次使用你给予前一条run命令的参数,这是很有用的. 利用set args 命令就可以修改发送给程序的参数,而使用show args 命令就可以查看其缺省参数的列表.

使用 gdb 调试 Python 进程

- yinseny - python.cn(jobs, news)
有时我们会想调试一个正在运行的Python进程,或者一个Python进程的coredump. 例如现在遇到一个mod_wsgi的进程僵死了,不接受请求,想看看究竟是运行到哪行Python代码呢. 这时就需要祭出gdb这个神器了. 确认你的gdb版本是>=7,gdb从版本7开始支持对Python的debug.

用gdb+nm调试php c extension程序

- ndv - 淘宝核心系统团队博客
最近在写Beanstalkd的php c extension客户端程序,写程序离不开调试,下面把调试中碰到的问题和解决方法和大家分享一下. .so写好了是给php脚本调用的,如果php脚本执行崩掉了,.so也只能在进程中饮恨而终,这时候php脚本调试经常用的echo, print_r, var_dump都派不上用场了.

GDB调试精粹及使用实例

- - CSDN博客推荐文章
当出现EXE_BAD_ACCESS, SIGABRT 及其他Crash时可以尝试用:. 要想运行准备调试的程序,可使用run命令,在它后面可以跟随发给该程序的任何参数,包括标准输入和标准输出说明符(<和>)和外壳通配符(*、. 如果你使用不带参数的run命令,gdb就再次使用你给予前一条run命令的参数,这是很有用的.

[C++] gdb高级调试方法

- - CSDN博客推荐文章
1,启动gdb的时候自动执行脚本. 注意:your_script里面只能有gdb命令. 不过我们都知道gdb命令里面有个shell指令,所以实际上这里可以做任何事. 在gdb里面有个attach指令,可以调试运行中的进程. 结合上面的-x参数,实际上我们可以写一个脚本,自动的attach到我们关心的进程上面,然后自动的做很多事情:比如设置trace命令并且continue.