gdb 调试 sysbench

前几天在写这篇文档的时候,发现sysbench对PostgreSQL libpq绑定变量使用的支持并不好。
《让 sysbench 支持 PostgreSQL 服务端绑定变量》

那么怎样跟踪出错的代码呢?
通过gdb跟踪是一种手段,但是sysbench在测试PostgreSQL libpq绑定时立即就退出。 通过pid来跟踪不太恰当,可以使用gdb的run指令来跟踪(之前没有仔细研究过gdb,还好有RDS PG内核团队小鲜肉给的方法,靠谱的团队,有问题立即就能找到靠谱的人)。
例如调试data程序

gdb date
(gdb) run
Starting program: /bin/date
[Thread debugging using libthread_db enabled]
Thu Apr 28 22:32:24 CST 2016

Program exited normally.

run后面加参数,实际上就是data命令加参数的效果一样

gdb date
(gdb) run +%F%t
Starting program: /bin/date +%F%t
[Thread debugging using libthread_db enabled]
2016-04-28
Program exited normally.

对于sysbench_pg,因为出错就立即退出,所以需要先加断点,然后再run,例如我们大概已经分析到sysbench_pg一定会运行的函数,设为断点,然后用单步调试。

(gdb) break [<file-name>:]<func-name>
(gdb) break [<file-name>:]<line-num>

例子 :

gdb ./sysbench_pg

(gdb) b sb_lua_db_execute
或
(gdb) b script_lua.c:sb_lua_db_execute
Breakpoint 1 at 0x40f130: file script_lua.c, line 851.

(gdb) run --test=lua/oltp_pg1.lua   --db-driver=pgsql   --pgsql-host=$PGDATA   --pgsql-port=1921   --pgsql-user=postgres   --pgsql-password=postgres   --pgsql-db=postgres   --oltp-tables-count=1   --oltp-table-size=1000000   --num-threads=1  --max-time=120  --max-requests=0 --report-interval=1 run

[Thread debugging using libthread_db enabled]
sysbench 0.5:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1
Report intermediate results every 1 second(s)
Random number generator seed is 0 and will be ignored

[New Thread 0x7ffff7e6c700 (LWP 10898)]
[New Thread 0x7ffff7e5b700 (LWP 10899)]
Threads started!

[Switching to Thread 0x7ffff7e5b700 (LWP 10899)]

Breakpoint 1, sb_lua_db_execute (L=0x8ab080) at script_lua.c:851
851     script_lua.c: No such file or directory.
        in script_lua.c
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.2.alios6.x86_64 libaio-0.3.107-10.1.alios6.x86_64

(gdb) n
863     in script_lua.c

(gdb) s
sb_lua_get_context (L=0x8ab080) at script_lua.c:1109
1109    in script_lua.c

查看对应的代码 :

$vi sysbench/scripting/script_lua.c
:set nu
:1109

1108 sb_lua_ctxt_t sb_lua_get_context(lua_State L)
1109 {

打印当前环境的变量值

(gdb) p L
$1 = (lua_State *) 0x8ab080

(gdb) p *L
$2 = {next = 0x7ffff00097b0, tt = 8 '\b', marked = 97 'a', status = 0 '\000', top = 0x8ab3a0, base = 0x8ab390, l_G = 0x8ab138, ci = 0x8a20a0, savedpc = 0x8b6d78, stack_last = 0x8ab560, stack = 0x8ab2f0, end_ci = 0x8a2168,
  base_ci = 0x8a2050, stacksize = 45, size_ci = 8, nCcalls = 1, hookmask = 0 '\000', allowhook = 1 '\001', basehookcount = 0, hookcount = 0, hook = 0, l_gt = {value = {gc = 0x8aa560, p = 0x8aa560, n = 9086304, b = 9086304}, tt = 5},
  env = {value = {gc = 0x8af150, p = 0x8af150, n = 9105744, b = 9105744}, tt = 5}, openupval = 0x0, gclist = 0x0, errorJmp = 0x7ffff7e5ac20, errfunc = 0}

(gdb) p *L->savedpc
$3 = 147525

一路回车,在这个位置抛出异常

sb_lua_db_execute (L=0x8ab080) at script_lua.c:943
943     script_lua.c: No such file or directory.
        in script_lua.c
(gdb)
942     in script_lua.c
(gdb)
943     in script_lua.c
(gdb)
946     in script_lua.c
(gdb)
945     in script_lua.c
(gdb)
946     in script_lua.c
(gdb)
948     in script_lua.c
(gdb)
lua_error (L=0x8ab080) at lapi.c:957
957     lapi.c: No such file or directory.
        in lapi.c
(gdb)
960     in lapi.c
(gdb)
luaG_errormsg (L=0x8ab080) at ldebug.c:600
600     ldebug.c: No such file or directory.
        in ldebug.c
(gdb)
601     in ldebug.c
(gdb)
610     in ldebug.c
(gdb)
609     in ldebug.c
(gdb)
610     in ldebug.c
(gdb)
609     in ldebug.c
(gdb)
luaD_throw (L=0x8ab080, errcode=2) at ldo.c:94
94      ldo.c: No such file or directory.
        in ldo.c
(gdb)
95      in ldo.c
(gdb)
94      in ldo.c
(gdb)
95      in ldo.c
(gdb)
96      in ldo.c
(gdb)
97      in ldo.c
(gdb) 

FATAL: failed to execute function `event': (null)
[Thread 0x7ffff7e5b700 (LWP 11124) exited]
[Thread 0x7ffff7e6c700 (LWP 11123) exited]

重来一遍,直接跟踪行号

gdb ./sysbench_pg
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-50.1.alios6)
Copyright (C) 2010 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/dege.zzz/sysbench/sysbench_pg...done.
(gdb) b script_lua.c:943
Breakpoint 1 at 0x40f2cd: file script_lua.c, line 943.
(gdb) run --test=lua/oltp_pg1.lua   --db-driver=pgsql   --pgsql-host=$PGDATA   --pgsql-port=1921   --pgsql-user=postgres   --pgsql-password=postgres   --pgsql-db=postgres   --oltp-tables-count=1   --oltp-table-size=1000000   --num-threads=1  --max-time=120  --max-requests=0 --report-interval=1 run
Starting program: /home/dege.zzz/sysbench/sysbench_pg --test=lua/oltp_pg1.lua   --db-driver=pgsql   --pgsql-host=$PGDATA   --pgsql-port=1921   --pgsql-user=postgres   --pgsql-password=postgres   --pgsql-db=postgres   --oltp-tables-count=1   --oltp-table-size=1000000   --num-threads=1  --max-time=120  --max-requests=0 --report-interval=1 run
[Thread debugging using libthread_db enabled]
sysbench 0.5:  multi-threaded system evaluation benchmark

Running the test with following options:
Number of threads: 1
Report intermediate results every 1 second(s)
Random number generator seed is 0 and will be ignored

[New Thread 0x7ffff7e6c700 (LWP 11347)]
[New Thread 0x7ffff7e5b700 (LWP 11348)]
Threads started!

FATAL: query execution failed: -268398832
[Switching to Thread 0x7ffff7e5b700 (LWP 11348)]

Breakpoint 1, sb_lua_db_execute (L=0x8ab080) at script_lua.c:943
943     script_lua.c: No such file or directory.
        in script_lua.c
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.2.alios6.x86_64 libaio-0.3.107-10.1.alios6.x86_64
(gdb) n
942     in script_lua.c

对应的代码
应该是在类型处理时出现了问题。

 908   / Rebind if needed /
 909   if (needs_rebind)
 910   {
 911     binds = (db_bind_t *)calloc(stmt->nparams, sizeof(db_bind_t));
 912     if (binds == NULL)
 913       luaL_error(L, "Memory allocation failure");
 914
 915     for (i = 0; i < stmt->nparams; i++)
 916     {
 917       param = stmt->params + i;
 918       binds[i].type = param->type;
 919       binds[i].is_null = &param->is_null;
 920       if (*binds[i].is_null != 0)
 921         continue;
 922       switch (param->type)
 923       {
 924         case DB_TYPE_INT:
 925           binds[i].buffer = param->buf;
 926           break;
 927         case DB_TYPE_CHAR:
 928           binds[i].buffer = param->buf;
 929           binds[i].data_len = &stmt->params[i].buflen;
 930           binds[i].is_null = 0;
 931           break;
 932         default:
 933           luaL_error(L, "Unsupported variable type");
 934       }
 935     }

 937     if (db_bind_param(stmt->ptr, binds, stmt->nparams))
 938       luaL_error(L, "db_bind_param() failed");
 939     free(binds);
 940   }
 941
 942   ptr = db_execute(stmt->ptr);
 943   if (ptr == NULL)
 944   {
 945     stmt->rs = NULL;
 946     if (ctxt->con->db_errno == SB_DB_ERROR_DEADLOCK)
 947       lua_pushnumber(L, SB_DB_RESTART_TRANSACTION);

gdb的详细用法可以参考gdb手册。

时间: 2024-09-20 00:04:20

gdb 调试 sysbench的相关文章

nginx模块_使用gdb调试nginx源码

工欲善其事必先利其器,如何使用调试工具gdb一步步调试nginx是了解nginx的重要手段. ps:本文的目标人群是像我这样初接触Unix编程的同学,如果有什么地方错误请指正. 熟悉gdb的使用 这里就不说了,谷歌一搜一堆,这里推荐一篇文章:GDB 命令详细解释 请重点看一下step,run,break,list,info,continue命令 下载nginx源码 这里使用nginx-1.0.14 src是源代码,auto文件夹是configure运行时候的各种命令集合 修改config并编译

Xcode的gdb调试

关于GDB 对于大多数Cocoa程序员来说,最常用的debugger莫过于Xcode自带的调试工具了.而实际上,它正是gdb的一个图形化包装.相对于gdb,图形化带来了很多便利,但同时也缺少了一些重要功能.而且在某些情况下,gdb反而更加方便.因此,学习gdb,了解一下幕后的实质,也是有必要的. gdb可以通过终端运行,也可以在Xcode的控制台调用命令.本文将通过终端讲述一些gdb的基本命令和技巧. 首先,我们来看一个例子:     #import <Foundation/Foundation

gcc/g++编译器和gdb调试器

gcc and g++分别是gnu的c & c++编译器 gcc/g++在执行编译工作的时候,总共需要4步 1.预处理,生成.i的文件[预处理器cpp]2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs]3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as]4.连接目标代码,生成可执行程序[链接器ld] [参数详解]-x language filename 设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根据约定C语言的后缀名称是.c的,而C++的后缀名是.C

编程-Linux中c语言多线程gdb调试“Cannot access memory at address”如何解决

问题描述 Linux中c语言多线程gdb调试"Cannot access memory at address"如何解决 程序的目的是做一个xml解析的工作. 部分代码如下: #define BUFLEN 10240 typedef struct buffer_t//需要操作的结构体 { char *buf; Bcsarray *bcsay; int bufnum; struct buffer_t *next; }databuf; databuf *buf, *bufs;//buf为链表

ubuntu下用gdb调试汇编提示The program has no registers now

问题描述 ubuntu下用gdb调试汇编提示The program has no registers now 我已经运行了程序,它还是这么提示,请问这是为什么?求高人解答 解决方案 参考info registers command Common errors If you run the info registers command without starting your program, you will get the The program has no registers now m

emacs进行gdb调试的相关问题

问题描述 emacs进行gdb调试的相关问题 为什么打开gdb后无法调试?这是因为我的程序哪里有问题嘛? 以下是我的程序: #include #include #include #include using namespace std; struct BinaryTreeNode{ int m_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; BinaryTreeNode* CreateBinaryTreeNode(int

经典的GDB调试命令

导语 在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect来查看当前程序的运行数据.print命令的格式是: print print / 是表达式,是你所调试的程序的语言的表达式(GDB可以调试多种编程语言),是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x.   一.表达式 print和许多GDB的命令一样,可以接受一个表达式,GDB会根据当前的程序运行的数据来计算这个表达式,既然是表达式,那么就可以是当前程序运行中的cons

今天新装了个ubuntu用gdb调试时总是出这个问题,求大神给看看。

问题描述 今天新装了个ubuntu用gdb调试时总是出这个问题,求大神给看看. 最简单的程序,, 结果出了些这 解决方案 会不会是没有写return? 解决方案二: printf.c是系统c库实现,你可以直接跳出来,继续下一句代码调试.

ndk-gdb 调试-android机程序gdb调试

问题描述 android机程序gdb调试 用ndk-gdb在android真机调试时,发现地址发生的偏移,变量n的实际地址是0x5a1f2e24, 但是gdb调试时 p &n 打印的却是 0x5a1f2d24,地址向低处偏移了256个字节,会是哪里的问题? 解决方案 http://laokaddk.blog.51cto.com/368606/1162257/ 解决方案二: 用GDB调试程序用GDB调试程序GDB调试程序