GDB 调试

前言

C++聊天服务器项目加上数据库连接池时出了bug。可我不会在Linux环境下调试,浪费了很多时间。虽然最后将这个bug解决了,但是这给了我一个警钟:必须要会GDB的简单使用
我将复现bug,使用GDB一步步地将bug揪出来。
其实这个bug,我事后回想了下,并不离谱,稍微推理下就应该知道大概在哪里出了岔子。

1、bug 复现

mysql Commands out of sync; you can't run this command now

数据库连接池在并发环境下,执行select后出错(用户登录)(insert随便用)(第一条select就报错)。当时的解决方向跑到了数据库的锁(被网上搜到的指偏了):读的时候对表加了独占锁。

现在给出不需要调试的找bug思路:第一条select就报错,但是在此之前数据库并没有读表!所以大概率不是锁的问题,而是登录模块出了问题。

当时的bug是这样的:处理登录功能会跳转到usermodel.cpp里面执行这个函数(未修改版):

// 根据用户号码查询用户信息
User UserModel::query(int id)
{
    // 1.组装sql语句
    char sql[1024] = {0};
    sprintf(sql, "select * from user where id = %d", id);

    MySQL mysql;
    MYSQL_RES *res = mysql.query(sql);
    if (res != nullptr)
    {
        MYSQL_ROW row = mysql_fetch_row(res);
        if (row != nullptr)
        {
            User user;
            user.setId(atoi(row[0]));
            user.setName(row[1]);
            user.setPwd(row[2]);
            user.setState(row[3]);
            mysql_free_result(res);
            return user;
        }
    }

    return User();
}

我是在已经写好的代码上改的,向线程池申请资源时不需要再连接,所以我把所有的connect()删了,但是这个角落的删了连接、且不是向池申请,所以是空连接。

ConnectionPool* cp = ConnectionPool::getConnectionPool();
shared_ptr<MySQL>mysql = cp->getConnection();
MYSQL_RES *res = mysql->query(sql);

那么,如果我当时会gdb调试的话,情况会怎样呢?

2、GDB

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

设置断点 b chatservice.cpp:67 之后使用 run运行到断点,再 n/s/finish 交替看运行过程。

比cout加ctrl点击还是要方便许多的。可以看到执行过程,将排查范围精准下来。


2024.2.26 更新

简单使用

ctrl+g显示行号 也可以 :set nu

b打断点

p打印,如果是打印表达式,表达式会被执行

set var可以改变变量的值,如循环把i的值改变 set var i = 8,它只是改变变量,比如本来要循环10次,把i改大后,循环次数会变少。

调试core文件

错误代码如下

#include <cstring>
#include <iostream>
using namespace std;

void bb(const int bh, const string xm)
{
    char* ptr = nullptr;
    *ptr = 3;
    //strcpy(ptr,xm.c_str());
}

void aa(const int no, const string name)
{
    bb(3, "冰冰");
}

int main()
{
    aa(8, "西施");
    return 0;
}

出现段错误后无法定位。Linux缺省不会生成core文件,需要修改系统参数。

先用ulimit -a查看当前用户的资源限制参数

[wsm@localhost app]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
...

看到core文件大小默认为0,我们要把它改为不限制,core的选项是-c,所以我们用-c

[wsm@localhost app]$ ulimit -c unlimited
[wsm@localhost app]$ ulimit -a
core file size          (blocks, -c) unlimited
...

再运行程序可以产生core文件

[wsm@localhost app]$ ./t2
段错误(吐核)
[wsm@localhost app]$ ls
core.28925  demo  demo01.cpp  t1  t1.cpp  t2  t2.cpp

然后运行gdb 程序名 core文件名

[wsm@localhost app]$ gdb t2 core.28925 
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/wsm/test/app/t2...done.
[New LWP 28925]
Core was generated by `./t2'.
Program terminated with signal 11, Segmentation fault.
#0  0x0000000000400869 in bb (bh=3, xm=...) at t2.cpp:8
8               *ptr = 3;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_64 libgcc-4.8.5-44.el7.x86_64 libstdc++-4.8.5-44.el7.x86_64

可以看到是第8行产生的段错误。

可以用bt查看函数调用栈

(gdb) bt
#0  0x0000000000400869 in bb (bh=3, xm="冰冰") at t2.cpp:8
#1  0x00000000004008b1 in aa (no=8, name="西施") at t2.cpp:14
#2  0x0000000000400927 in main () at t2.cpp:19

调试正在运行中的程序

gdb 程序名 -p 进程编号
[wsm@localhost app]$ ps -ef | grep t3
wsm       29177  29058  0 20:45 pts/1    00:00:00 ./t3
wsm       29231   2903  0 20:45 pts/0    00:00:00 grep --color=auto t3
[wsm@localhost app]$ gdb t3 -p 29177
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
...

开始调试后正在运行的程序会停住,调试结束后程序继续运行。调试如果改变了某一变量的值,结束后这个变量不会复原。

调试过程中将ii赋值为999
ii=32
ii=33
ii=999
ii=1000
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇