澳门威尼斯人网址接纳GDB举办四线程调试,26分钟GDB调试快捷突破

引言 Linus心灵鸡汤

引言 Linus心灵鸡汤

一、多线程调试

  在*nix开发中有道卡叫gdb调试,不管你怎么搞.
它依旧在那丝毫不会松动.明日问候3个 活着的传说 Linus Torvalds

  在*nix开发中有道卡叫gdb调试,不管你怎么搞.
它如故在那丝毫不会松动.前些天问候三个 活着的传说 Linus Torvalds

二十四线程调试首要就是上边多少个指令:

 澳门威尼斯人网址 1

 澳门威尼斯人网址 2

info thread 查看当前历程的线程。 thread <ID>
切换调试的线程为指定ID的线程。 break file.c:100 thread all
 在file.c文件第8、0行处为保有通过此处的线程设置断点。 set
scheduler-locking
off|on|step,这么些是问得最多的。在采纳step只怕continue命令调试当前被调剂线程的时候,其余线程也是同时施行的,怎么只让被调试程序执行呢?通过这几个命令就可以完毕这一个须求。
off 不锁定任何线程,也等于持有线程都推行,那是暗中同意值。 on
只有当前被调试程序会举行。 step
在单步的时候,除了next过2个函数的情事(熟知景况的人或许知道,那实际上是三个设置断点然后continue的一颦一笑)以外,唯有当前线程会进行。 

  Unix 始于上个世纪60年间,在70年份拿到了疾速的上扬,

  Unix 始于上个世纪60年间,在70年份得到了赶快的上进,

二、调试宏

那儿的李纳斯还躺在外祖父公寓的源头里睡大觉,假诺不是新兴 Unix
王国自断命根,

此时的李纳斯还躺在伯公公寓的摇篮里睡大觉,如果不是新兴 Unix
王国自乱了阵脚,

以此标题超多。在GDB下,我们无能为力print宏定义,因为宏是预编译的。然而大家依然有艺术来调试宏,那一个要求GCC的匹配。

出现阵营分化和法律纠纷,大概 Linux 系统根本都不会并发。真实的情事是,

并发阵营差别和法律纠纷,可能 Linux 系统根本都不会油可是生。真实的情况是,

在GCC编译程序的时候,加上-ggdb3参数,那样,你就足以调试宏了。

Unix
浪费了大把的时刻和时机,如同就是为着等待那个大鼻子、头发凌乱的芬兰共和国区镇长大,然后一决高下。

Unix
浪费了大把的年华和机遇,如同就是为着等待那几个大鼻子、头发凌乱的芬兰区镇长大,然后一决高下。

此外,你可以利用下述的GDB的宏调试命令 来查看相关的宏。

  李纳斯拿到了投机的光阴,他一刻不停的磨练本身的技艺,在中午的微光中锻炼算法,

  李纳斯拿到了祥和的岁月,他一刻不停的锤炼本人的技艺,在早上的微光中陶冶算法,

info macro –
你可以查看这么些宏在什么文件里被引用了,以及宏定义是怎么着的。 macro –
你可以查看宏展开的楷模。

在希腊雅典的雪山上编译代码,随时处处补充的粮草和器械。

在休斯敦的雪山上编译代码,随时遍地补充的粮草和武器。

 

二十一年之后,李纳斯抚着明显的刃片上路了,他要去寻找属于程序员的万丈荣誉。[

二十一年过后,李纳斯抚着明亮的刀口上路了,他要去搜寻属于程序员的参天荣誉。[

三、源文件

  I simply know better than you, that’s why I’m your god.

  I simply know better than you, that’s why I’m your god.

本条标题问的也是诸多的,太多的朋友都说找不到源文件。在此处作者想唤醒大家做上面的检查:

                          - –  Linus Torvalds

                          - –  Linus Torvalds

编译程序员是或不是丰裕了-g参数以含有debug新闻。
路径是还是不是设置科学了。使用GDB的directory命令来设置源文件的目录。

]

]

上面给二个调试/bin/ls的以身作则(ubuntu下)

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ apt-get sourcecoreutils
$ sudoapt-get installcoreutils-dbgsym
$ gdb /bin/ls
GNU gdb (GDB) 7.1-ubuntu
(gdb) list main
1192    ls.c: No such fileor directory.
inls.c
(gdb) directory ~/src/coreutils-7.4/src/
Source directories searched: /home/hchen/src/coreutils-7.4:$cdir:$cwd
(gdb) list main
1192        }
1193    }
1194
1195    int
1196    main (int argc, char **argv)
1197    {
1198      int i;
1199      struct pending *thispend;
1200      int n_files;
1201

序言  gdb 初始调试起来上手

序言  gdb 开头调试起来上手

四、条件断点

1. 打开core, 采集程序崩溃的情形

1. 拉开core, 采集程序崩溃的景况

标准断点是语法是:break  [where] if
[condition],那种断点真是11分管用。特别是在贰个循环或递归中,或是要监视有个别变量。注意,那个装置是在GDB中的,只但是每经过那么些断点时GDB会帮你检查一下条件是还是不是满意。

  首先你跟着作者做开启core崩溃状态采集. 可以通过 ulimit
-c 查看 若是是0表示尚无开启. 开启根据上边操作

  首先你跟着自个儿做开启core崩溃状态采集. 可以经过 ulimit
-c 查看 假设是0表示不曾开启. 开启根据上面操作

五、命令行参数

su root

vi /etc/profile
Shift + G
i
# No core files by default 0, unlimited is oo
ulimit -S -c unlimited > /dev/null 2>&1
wq!

source /etc/profile
su root

vi /etc/profile
Shift + G
i
# No core files by default 0, unlimited is oo
ulimit -S -c unlimited > /dev/null 2>&1
wq!

source /etc/profile

有时,大家要求调剂的程序需要有命令行参数,很多有情人都不知晓怎么设置调试的先后的命令行参数。其实,有三种办法:

地点shell 操作是 在
/etc/profile 最终一行添加 上面安装全局开启 core文件调试,大小不限. 最终 立刻生效.

上面shell 操作是 在
/etc/profile 最终一行添加 上边安装全局开启 core文件调试,大小不限. 最终 立刻生效.

gdb命令行的 –args 参数 gdb环境中 set args命令。 

再跟着本人做, 因为变化的core文件同名会覆盖. 这里为其丰盛2个 core命名规则, 让其变成 [core.pid] 格式.

再接着本身做, 因为变化的core文件同名会覆盖. 那里为其充裕一个 core命名规则, 让其变为 [core.pid] 格式.

六、gdb的变量

su root

vi /etc/sysctl.conf
Shift + G
i

# open, add core.pid 
kernel.core_pattern = ./core_%t_%p_%e
kernel.core_uses_pid = 1

wq!

sysctl -p /etc/sysctl.conf
su root

vi /etc/sysctl.conf
Shift + G
i

# open, add core.pid 
kernel.core_pattern = ./core_%t_%p_%e
kernel.core_uses_pid = 1

wq!

sysctl -p /etc/sysctl.conf

有时候,在调试程序时,大家不单单只是翻开运维时的变量,大家还能直接设置程序中的变量,以模拟一些很难在测试中出现的状态,相比一些失误,或是switch的分层语句。使用set命令可以修改程序中的变量。


/etc/sysctl.conf 文件中添加系统配置. 前面立刻启用. 最终是上面景况表示core启用都做好了.


/etc/sysctl.conf 文件中添加系统配置. 后边立时启用. 最终是上边情状表示core启用都搞好了.

除此以外,你精通gdb中也足以有变量吗?似乎shell一样,gdb中的变量以$先导,比如您想打印3个数组中的个个成分,你可以如此:

澳门威尼斯人网址 3

澳门威尼斯人网址 4

1
2
3
4
5
(gdb) set$i = 0
  
(gdb) p a[$i++]
  
…  #然后就一路回车下去了

(上面是ubuntu 15.10 环境中, 后边测试用的是centos 6.4)

(下面是ubuntu 15.10 环境中, 后边测试用的是centos 6.4)

本来,那里只是给2个演示,表示程序的变量和gdb的变量是足以相互的。

 

 

七、x命令

2. 粗略接触 GDB , 先河调剂 r n p

2. 简练接触 GDB , 开端调剂 r n p

大概,你很喜欢用p命令。所以,当您不领悟变量名的时候,你大概会惊慌,因为p命令总是须要三个变量名的。x命令是用来查看内存的,在gdb中
“help x” 你可以查阅其匡助。

第多个示范代码 heoo.c

先是个示范代码 heoo.c

x/x 以十六进制输出 x/d 以十进制输出 x/c 以单字符输出 x/i  反汇编 –
常常,大家会使用 x/10i $ip-20
来查阅当前的汇编($ip是指令寄存器)x/s 以字符串输出
八、command命令

#include <stdio.h>

int g_var = 0;

static int _add(int a, int b) {
    printf("_add callad, a:%d, b:%d\n", a, b);
    return a+b;
}

int main(void) {
    int n = 1;

    printf("one n=%d, g_var=%d\n", n, g_var);
    ++n;
    --n;

    g_var += 20;
    g_var -= 10;
    n = _add(1, g_var);
    printf("two n=%d, g_var=%d\n", n, g_var);

    return 0;
}
#include <stdio.h>

int g_var = 0;

static int _add(int a, int b) {
    printf("_add callad, a:%d, b:%d\n", a, b);
    return a+b;
}

int main(void) {
    int n = 1;

    printf("one n=%d, g_var=%d\n", n, g_var);
    ++n;
    --n;

    g_var += 20;
    g_var -= 10;
    n = _add(1, g_var);
    printf("two n=%d, g_var=%d\n", n, g_var);

    return 0;
}

有部分对象问小编什么自动化调试。那里向大家介绍command命令,不难的明白一下,其就是把一组gdb的吩咐打包,有点像字处理软件的“宏”。上面是二个示范:

我们上边从图说起.(假诺用视频说更好,文字和图意义在于查询方便.更简便易行)

我们下边从图说起.(如果用视频说更好,文字和图意义在于查询方便.更简短)

1
2
3
4
5
6
7
8
9
10
(gdb) breakfunc
Breakpoint 1 at 0x3475678: filetest.c, line 12.
(gdb) command1
Type commands forwhen breakpoint 1 is hit, one per line.
End with a line saying just "end".
>print arg1
>print arg2
>print arg3
>end
(gdb)

澳门威尼斯人网址 5

澳门威尼斯人网址 6

当大家的断点到达时,自动执行command中的四个指令,把func的多少个参数值打出去。

率先个指令 gdb heoo.out 表示 gdb加载 heoo.out 起始调试. 若是需要动用gdb调试的话编译的时候 gcc 须要添加
-g命令.

率先个指令 gdb heoo.out 表示 gdb加载 heoo.out 开首调试. 如若须求接纳gdb调试的话编译的时候 gcc 须求丰裕-g命令.

 

中间l命令表示 查看加载源码内容. 下边将演示怎样加断点.

里面l命令表示 查看加载源码内容. 上边将演示怎么着加断点.

设置core环境
uname -a 查看机器参数
ulimit -a 查看私自认同参数
ulimit -c 1024  设置core文件大小为1024
ulimit -c unlimit 设置core文件大小为极端

澳门威尼斯人网址 7

澳门威尼斯人网址 8

 
多线程若是dump,多为段错误,一般都关系内存不合法读写。能够如此处理,使用上面的通令打开系统开关,让其可以在死掉的时候生成
core文件。   
ulimit -c unlimited

r 表示调试的次第开端运维.

r 表示调试的顺序初阶运转.

线程调试命令
(gdb)info threads 
来得当前可调节的持无线程,各个线程会有二个GDB为其分配的ID,前边操作线程的时候会用到这几个ID。 
前面有*的是目前调试的线程。

澳门威尼斯人网址 9

澳门威尼斯人网址 10

(gdb)thread ID 
切换当前调试的线程为指定ID的线程。

p 命令表示 打印值. n表示经过调试, 到下一步. 不管敬仲进度怎样都不进去.
直接四遍跳过.

p 命令表示 打印值. n表示经过调试, 到下一步. 不管敬仲进程怎么着都不进来.
直接两回跳过.

(gdb)thread apply ID1 ID2 command 
让2个依旧八个线程执行GDB命令command。
(gdb)thread apply all command 
让具备被调剂线程执行GDB命令command。

澳门威尼斯人网址 11 

澳门威尼斯人网址 12 

(gdb)set scheduler-locking off|on|step 
估价是事实上应用过二十四线程调试的人都得以发现,在使用step大概continue命令调试当前被调剂线程的时候,其余线程也是还要执行的,怎么只让被调试程序执行吗?通过这些命令就足以兑现这几个须要。
off 不锁定任何线程,相当于颇具线程都执行,这是暗许值。 
on 只有当前被调试程序会履行。 
step
在单步的时候,除了next过3个函数的场地(熟谙意况的人大概知道,这实际是一个装置断点然后continue的一言一动)以外,唯有当前线程会实施。

地点用的s 表示单步调试, 蒙受子函数,会跻身函数内部调试.

地点用的s 表示单步调试, 蒙受子函数,会进去函数内部调试.

//显示线程堆栈音信
(gdb) bt 
观测全体的调用栈

小结一下 . l 查看源码 ,
b 加断点, r 起头运行调试, n 下一步, s下一步不过会跻身子函数. p 输出数据.

小结一下 . l 查看源码 ,
b 加断点, r 初始运转调试, n 下一步, s下一步可是会进来子函数. p 输出数据.

(gdb) f 3
调用框层次

到这里gdb 基本会用了. 是或不是也很不难. 直白. 小代码可以任由调试了.

到那里gdb 基本会用了. 是否也很不难. 直白. 小代码可以不管调试了.

(gdb) i locals  
浮现全体当前调用栈的有所变量

观望那里基础知识普及达成了. 后边可以不看了. 有空子再看. 好那大家随后扯.

总的来看那里基础知识普及达成了. 前边可以不看了. 有空子再看. 好那大家随后扯.

 

 

 

 

正文 第三有个别 gdb别的开发中用的一声令下

正文 第壹局地 gdb其余开发中用的命令

最终用自身几个例证表明下:

  起来扯一点, linux总是敲命令操作, 也很不安全. 有时候晕了. 写这么编译命令.

  开班扯一点, linux总是敲命令操作, 也很不安全. 有时候晕了. 写这么编译命令.

 

gcc -g -Wall -o heoo.c heoo.out
gcc -g -Wall -o heoo.c heoo.out

int main(int argc, char* argv[])
{
    pthread_mutex_init(&mutex_info, NULL);
    sem_init(&sem_note, 0, 0);
    pthread_attr_init(&g_attr);
    pthread_attr_setdetachstate(&g_attr,
PTHREAD_CREATE_DETACHED);
    pthread_t thread_id = 0;
    pthread_create(&thread_id, &g_attr, do_client, NULL);
    pthread_create(&thread_id, &g_attr, do_wdog, NULL);

非凡恐惧, heoo.c 代码删除了. heoo.out
=> heoo.c 先创立后变卦战败退出. 原先的始末被抹掉了. 哈哈. 服务器开发, 经验不足, 熟知度不够.自身都怕本人.

那么些害怕, heoo.c 代码删除了. heoo.out
=> heoo.c 先成立后转移失利退出. 原先的始末被抹掉了. 哈哈. 服务器开发, 经验不足, 熟悉度不够.自个儿都怕本身.

   return 0;

1.  gdb 其它常用命令用法 c q b info

1.  gdb 其余常用命令用法 c q b info

}

首先看 用到的调剂文件 houge.c

第壹看 用到的调试文件 houge.c

这里调用多个线程, pthread_create(&thread_id, &g_attr, do_client,
NULL);
            pthread_create(&thread_id, &g_attr, do_wdog,
NULL);

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
 * arr 只能是数组
 * 返回当前数组长度
 */
#define LEN(arr) (sizeof(arr)/sizeof(*arr))

// 简单数组打印函数
static void _parrs(int a[], int len) {
    int i = -1;
    puts("当前数组内容值如下:");

    while(++i < len) 
        printf("%d ", a[i]);    
    putchar('\n');
}

// 简单包装宏, arr必须是数组
#define PARRS(arr) \
    _parrs(arr, LEN(arr))

#define _INT_OLD (23)

/*
 * 主函数,简单测试
 * 测试 core文件, 
 * 测试 宏调试
 * 测试 堆栈内存信息
 */
int main(void) {
    int i;
    int a[_INT_OLD];
    int* ptr = NULL;    

    // 来个随机数填充值吧
    srand((unsigned)time(NULL));
    for(i=0; i<LEN(a); ++i)
        a[i] = rand()%222;

    PARRS(a);

    //全员加double, 包含一个错误方便测试
    for(i=1; i<=LEN(a); ++i)
        a[i] <<= 1;
    PARRS(a);

    // 为了错,强制错
    *ptr = 0;

    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/*
 * arr 只能是数组
 * 返回当前数组长度
 */
#define LEN(arr) (sizeof(arr)/sizeof(*arr))

// 简单数组打印函数
static void _parrs(int a[], int len) {
    int i = -1;
    puts("当前数组内容值如下:");

    while(++i < len) 
        printf("%d ", a[i]);    
    putchar('\n');
}

// 简单包装宏, arr必须是数组
#define PARRS(arr) \
    _parrs(arr, LEN(arr))

#define _INT_OLD (23)

/*
 * 主函数,简单测试
 * 测试 core文件, 
 * 测试 宏调试
 * 测试 堆栈内存信息
 */
int main(void) {
    int i;
    int a[_INT_OLD];
    int* ptr = NULL;    

    // 来个随机数填充值吧
    srand((unsigned)time(NULL));
    for(i=0; i<LEN(a); ++i)
        a[i] = rand()%222;

    PARRS(a);

    //全员加double, 包含一个错误方便测试
    for(i=1; i<=LEN(a); ++i)
        a[i] <<= 1;
    PARRS(a);

    // 为了错,强制错
    *ptr = 0;

    return 0;
}

怎么进去do_client函数调试呢?

一致须要细致看下边图中利用的命令. 首先对前言部分加深一些. 看上边

如出一辙须求细致看下边图中行使的命令. 首先对前言部分加深一些. 看上边

首先进入gdb调试下,

澳门威尼斯人网址 13

澳门威尼斯人网址 14

(gdb) info thread  //查看do_client是哪个线程

这一个图是前言的补充, c跳过直至下3个断点处, q代表程序退出.

本条图是前言的增补, c跳过直至下2个断点处, q代表程序退出.

(gdb) break  do_clien //那就再函数do_client函数体初阶出设立断点

在 houge.c 中我们伊始调试. 一周转段错误, 出现了我们的 core.pid 文件

在 houge.c 中大家初叶调试. 一周转段错误, 出现了作者们的 core.pid 文件

(gdb) c    //调到断点处

澳门威尼斯人网址 15

澳门威尼斯人网址 16

(gdb) next  //那里单步调试不就多说了

通过 gdb houge.out core.27047 开班调试. 登时定位出来了错误原因.

通过 gdb houge.out core.27047 先导调试. 立时定位出来了错误原因.

2. 调节 内存堆栈消息

2. 调剂 内存堆栈音讯

澳门威尼斯人网址 17

澳门威尼斯人网址 18

刚起先 print a
, 在main中作为数组处理.打印的音信多. 前面在_add函数中, a就是个形参数组地址.

刚初始 print a
, 在main中作为数组处理.打印的消息多. 前面在_add函数中, a就是个形参数组地址.

主要看 info args  查看当前函数参数值

主要看 info args  查看当前函数参数值

info locals 看当前函数栈上值新闻, info registers 表示查看寄存器值.

info locals 看当前函数栈上值音信, info registers 表示查看寄存器值.

后面查阅内存音信 需求记得东西多一些. 先看图

后面翻看内存音讯 须求记得东西多一些. 先看图

澳门威尼斯人网址 19

澳门威尼斯人网址 20

x /23dw a 意思是  查看 从a地址初始 二十三个 4字节 有标志十进制数 输出.

x /23dw a 意思是  查看 从a地址开首 2二个 4字节 有标志十进制数 输出.

有关x 尤其详细见上面

关于x 尤其详细见上面

用gdb查看内存格式: 
    x /nfu ptr

说明
x 是 examine 的缩写
n表示要显示的内存单元的个数

f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。

u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节

Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes)

ptr 表示从那个地址开始
用gdb查看内存格式: 
    x /nfu ptr

说明
x 是 examine 的缩写
n表示要显示的内存单元的个数

f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。

u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节

Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes)

ptr 表示从那个地址开始

以此命令常用于监测内存变化.调试中专门常用.

其一命令常用来监测内存变化.调试中特地常用.

3. gdb 设置规范断点

3. gdb 设置标准断点

澳门威尼斯人网址 21

澳门威尼斯人网址 22

很简单 b 17 if i ==
8.
 在17行设置3个断点,并且唯有i==8的时候才会触发.

很简单 b 17 if i ==
8.
 在17行设置1个断点,并且唯有i==8的时候才会触发.

4. gdb 删除断点

4. gdb 删除断点

gdb 删除有d 前面跟断点索引1,2,3..

gdb 删除有d 前边跟断点索引1,2,3..

clear 行数或名称. 删除哪一行断点. 看下边演示

clear 行数或名称. 删除哪一行断点. 看上面演示

澳门威尼斯人网址 23

澳门威尼斯人网址 24

到那里 介绍的gdb调试技巧基本都够用了. 感觉用图片ide,例如vs调试也就用到那几个了.

到那里 介绍的gdb调试技巧基本都够用了. 感觉用图形ide,例如vs调试也就用到那些了.

揣度gdb调试突破20min千古了.够用了.  前面能够不用看了.

估价gdb调试突破20min与世长辞了.够用了.  前边可以不用看了.

 

 

正文 第1、局地 gdb 二十四线程多进度调试

正文 第三,部分 gdb 二十四线程多进度调试

  到这里实战中用的火候少了, 也就老鸟会用上些. 那有的可以调剂,倒霉调试. 一般一调估摸小半天就走了. 好,那大家处理最后10min.

  到此处实战中用的时机少了, 也就老鸟会用上些. 那部分能够调节,不佳调试. 一般一调估算小半天就走了. 好,那大家处理最终10min.

1. 率先对地点正文第叁某些加深 gdb调试宏

1. 先是对地点正文第3片段加深 gdb调试宏

澳门威尼斯人网址 25

澳门威尼斯人网址 26

率先看上面命令 

先是看上边命令 

  macro expand 宏(参数) => 拿到宏导出内容.

  macro expand 宏(参数) => 获取宏导出内容.

  info macro 宏名 => 宏定义内容

  info macro 宏名 => 宏定义内容

若果你须求动用上边gdb功用, 查看和导出宏的话.还亟需gcc 辅助,生成的时候增进
-ggdb3如下

假诺你须要拔取上边gdb功效, 查看和导出宏的话.还需求gcc 扶助,生成的时候增进
-ggdb3如下

gcc -Wall -ggdb3 -o houge.out houge.c
gcc -Wall -ggdb3 -o houge.out houge.c

就能够使用了. 增添一下 对此 gcc 编译的有个经过叫做 预编译 gcc -E -o
*.i *.c.

就足以采纳了. 扩张一下 对于 gcc 编译的有个进度叫做 预编译 gcc -E -o
*.i *.c.

那时候处理多数宏,直接开展, 也足以查阅最后结果. 也算也是三个黑科学和技术.

那会儿处理多数宏,直接开展, 也可以查阅最终结果. 也算也是多个黑科学和技术.

2. 开班二十三八线程调试

2. 起头三十六线程调试

率先看测试用例 dasheng.c

先是看测试用例 dasheng.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// 声明一个都用的量
static int _old;

// 线程跑的函数
static void* _run(void* arg) {
    int piyo = 10;    
    int n = *(int*)arg;
    int i;

    //设置线程分离
    pthread_detach(pthread_self());

    for(i=0; i<n; ++i) {
        printf("n=%d, i=%d\n", n, i);
        ++_old;
        printf("n=%d, piyo = %d, _old=%d\n", n, piyo, _old);
    }

    return NULL;
}

#define _INT_PTX (3)

int main(void) {
    int i, rt, j;
    pthread_t tx[_INT_PTX];

    puts("main beign");    

    for(i=0; i<_INT_PTX; ++i) {
        // &i 是有问题的, 但是这里为了测试, 可以乱搞
        rt = pthread_create(tx+i, NULL, _run, &i);
        if(rt < 0) {
            printf("pthread_create create error! rt = %d, i=%d\n", rt, i);
            break;
        }
    }

    //CPU忙等待
    for(j=0; j<1000000000; ++j)
        ;        
    puts("end");    

    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// 声明一个都用的量
static int _old;

// 线程跑的函数
static void* _run(void* arg) {
    int piyo = 10;    
    int n = *(int*)arg;
    int i;

    //设置线程分离
    pthread_detach(pthread_self());

    for(i=0; i<n; ++i) {
        printf("n=%d, i=%d\n", n, i);
        ++_old;
        printf("n=%d, piyo = %d, _old=%d\n", n, piyo, _old);
    }

    return NULL;
}

#define _INT_PTX (3)

int main(void) {
    int i, rt, j;
    pthread_t tx[_INT_PTX];

    puts("main beign");    

    for(i=0; i<_INT_PTX; ++i) {
        // &i 是有问题的, 但是这里为了测试, 可以乱搞
        rt = pthread_create(tx+i, NULL, _run, &i);
        if(rt < 0) {
            printf("pthread_create create error! rt = %d, i=%d\n", rt, i);
            break;
        }
    }

    //CPU忙等待
    for(j=0; j<1000000000; ++j)
        ;        
    puts("end");    

    return 0;
}

编译命令

编译命令

gcc -Wall -g -o dasheng.out dasheng.c -lpthread
gcc -Wall -g -o dasheng.out dasheng.c -lpthread

那先看上面测试图

那先看上边测试图

澳门威尼斯人网址 27

澳门威尼斯人网址 28

上面 info threads 查看全体运维的线程消息. *代表近年来调试的线程.

上面 info threads 查看全部运营的线程音讯. *意味着近日调试的线程.

后面 l _run 代表查看
_run附近代码. 
当然还有 l 16 查看16行附近文件内容.

后面 l _run 代表查看
_run附近代码. 
本来还有 l 16 查看16行附近文件内容.

gdb二十四线程切换 测试如下

gdb二十四线程切换 测试如下

澳门威尼斯人网址 29

澳门威尼斯人网址 30

 thread
3代表切换成第6个线程, info threads 第二列id 就是 thread 切换的id.

 thread
3表示切换来首个线程, info threads 第1列id 就是 thread 切换的id.

上边测试线程 固然你切换成 thread
3. 其余线程依旧在跑的. 大家用下边发号施令 只让待调试的线程跑. 别的线程阻塞.

上边测试线程 即使你切换成 thread
3. 其余线程依旧在跑的. 大家用上边发号施令 只让待调试的线程跑. 其它线程阻塞.

澳门威尼斯人网址 31

澳门威尼斯人网址 32

set scheduler-locking on  开端三十六线程单独调试. 不用了 设置 set
scheduler-locking off 
关闭. 又会回到你调试那几个, 别的线程不阻塞.

set scheduler-locking on  发轫三十二线程单独调试. 不用了 设置 set
scheduler-locking off 
关闭. 又会重返你调试那么些, 其它线程不阻塞.

澳门威尼斯人网址 33

澳门威尼斯人网址 34

小结 十二线程调试常用就那四个实用命令

小结 八线程调试常用就那多少个实用命令

info threads

info threads

thread id

thread id

set scheduler-locking on/off

set scheduler-locking on/off

分级是查看,切换,设置同步调试.到那边二十四线程调试基本完工了.

各自是翻开,切换,设置同步调试.到那里八线程调试基本竣事了.

3. 先河gdb 多进程调试

3. 起来gdb 多进度调试

第2看 liaobude.c 测试代码

先是看 liaobude.c 测试代码

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

// 声明一个都用的量
static int _old;

// 线程跑的函数
static void _run(int n) {
    int piyo = 10;    
    int i;

    ++n;    
    for(i=0; i<n; ++i) {
        printf("n=%d, i=%d\n", n, i);
        ++_old;
        printf("n=%d, piyo = %d, _old=%d\n", n, piyo, _old);
    }
}

#define _INT_PTX (3)

int main(void) {
    int i;
    pid_t rt;

    puts("main beign");    

    for(i=0; i<_INT_PTX; ++i) {
        // &i 是有问题的, 但是这里为了测试, 可以乱搞
        rt = fork();
        if(rt < 0) {
            printf("fork clone error! rt = %d, i=%d\n", rt, i);
            break;
        }
        if(rt == 0) {
            _run(i);
            exit(EXIT_FAILURE);
        }
    }

    //等待子进程结束
  for(;;) {
    rt = waitpid(-1, NULL, WNOHANG);
    if(rt>=0 || errno==EINTR)
      continue;
    break;
  }   

    puts("end");    

    // 这里继续等待 
    for(i=0; i<190; ++i){
        printf("等待 有缘人[%d]!\n", i);
        sleep(1);
    }    

    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

// 声明一个都用的量
static int _old;

// 线程跑的函数
static void _run(int n) {
    int piyo = 10;    
    int i;

    ++n;    
    for(i=0; i<n; ++i) {
        printf("n=%d, i=%d\n", n, i);
        ++_old;
        printf("n=%d, piyo = %d, _old=%d\n", n, piyo, _old);
    }
}

#define _INT_PTX (3)

int main(void) {
    int i;
    pid_t rt;

    puts("main beign");    

    for(i=0; i<_INT_PTX; ++i) {
        // &i 是有问题的, 但是这里为了测试, 可以乱搞
        rt = fork();
        if(rt < 0) {
            printf("fork clone error! rt = %d, i=%d\n", rt, i);
            break;
        }
        if(rt == 0) {
            _run(i);
            exit(EXIT_FAILURE);
        }
    }

    //等待子进程结束
  for(;;) {
    rt = waitpid(-1, NULL, WNOHANG);
    if(rt>=0 || errno==EINTR)
      continue;
    break;
  }   

    puts("end");    

    // 这里继续等待 
    for(i=0; i<190; ++i){
        printf("等待 有缘人[%d]!\n", i);
        sleep(1);
    }    

    return 0;
}

编译命令

编译命令

gcc -Wall -g -o liaobude.out liaobude.c
gcc -Wall -g -o liaobude.out liaobude.c

 其实对多进度调试, 先介绍二个 常用的,
调试正在运营的程序. 首先让 ./liaobude.out 跑起来.

 其实对多进度调试, 先介绍2个 常用的,
调试正在运营的程序. 首先让 ./liaobude.out 跑起来.

澳门威尼斯人网址 35

澳门威尼斯人网址 36

 再通过 ps -ef 找到必要调剂的进程. 复制进度文件讲述符pid.

 再经过 ps -ef 找到要求调剂的进度. 复制进程文件讲述符pid.

此时运转gdb.

此刻运行gdb.

attach pid

attach pid

gdb就把pid这一个进度加载进来了. 加载的历程会阻塞到当下正值周转的地点. 直到使用命令控制. 那几个效果如故拾叁分猛的.

gdb就把pid这几个进程加载进来了. 加载的长河会阻塞到方今正值运营的地点. 直到使用命令控制. 这几个成效如故十分猛的.

末段介绍
过程调试的关于命令(需求最新的gdb才会支持). 多进度的调节思路和二十四线程调试流程很相似.

终极介绍
进度调试的有关命令(需求最新的gdb才会帮忙). 多进程的调剂思路和二十八线程调试流程很相似.

GDB可以同时调试多个程序。
只需要设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值:on)即可。

   设置方法:set follow-fork-mode [parent|child]   set detach-on-fork [on|off]

   查询正在调试的进程:info inferiors
   切换调试的进程: inferior <infer number>
GDB可以同时调试多个程序。
只需要设置follow-fork-mode(默认值:parent)和detach-on-fork(默认值:on)即可。

   设置方法:set follow-fork-mode [parent|child]   set detach-on-fork [on|off]

   查询正在调试的进程:info inferiors
   切换调试的进程: inferior <infer number>

切切实实的意趣有

实际的意味有

set follow-fork-mode [parent|child]   set
detach-on-fork [on|off]

set follow-fork-mode [parent|child]   set
detach-on-fork [on|off]

 parent                   on               只调试主进度(gdb暗中认可)
 child                      on               只调试子进程
 parent                   off             
同时调试多个经过,gdb跟主进度,子过程block在fork地点
 child                      off             
同时调试三个进程,gdb跟子进度,主进度block在fork地方

 parent                   on               只调试主进度(gdb专断认同)
 child                      on               只调试子进度
 parent                   off             
同时调试四个进度,gdb跟主进度,子过程block在fork地方
 child                      off             
同时调试八个进程,gdb跟子进度,主进程block在fork地方

越是详细的 gdb 多进程调试demo 可以参考 
http://blog.csdn.net/pbymw8iwm/article/details/7876797

一发详实的 gdb 多进程调试demo 可以参考 
http://blog.csdn.net/pbymw8iwm/article/details/7876797

运用办法和线程调试思路是一律的.
就是gdb 的吩咐换了字符. 工作中多进程调试境遇少. 

使用形式和线程调试思路是千篇一律的.
就是gdb 的指令换了字符. 工作中多进程调试遭遇少. 

相见了很少用gdb调试. 会用上面2种调试好法子

赶上了很少用gdb调试. 会用上边2种调试好点子

2) 写单元测试

2) 写单元测试

3) 打日志检测日志,分析

3) 打日志检测日志,分析

到这里 gdb贰拾柒秒钟内容讲解完毕. 多试试写写练一练, gdb基本突破没分外.

到那里 gdb2八分钟内容讲解落成. 多试试写写练一练, gdb基本突破没非常.

 

 

后记

后记

  错误是免不了的, 有题目能够随时交流. 拜, 礼拜日清晨欢悦. 希望明天照例是个好天气

  错误是免不了的, 有失常态得以每十一日交换. 拜, 周天午后欢愉. 希望后天依旧是个好天气

相关文章