C gdb使用rand()打印变量集的长值
我正在使用C gdb使用rand()打印变量集的长值,c,random,gdb,watchpoint,C,Random,Gdb,Watchpoint,我正在使用gdb脚本来观察变量的变化,使用awatch: #/bin/bash #编撰 gcc-Wall-pedantic-g-o demo.c #编译错误时退出 如果[$?-ne 0];然后 出口 fi #用标题覆盖trace.gdb的内容 echo“#Watch var”>trace.gdb #不要每次分页时都停止 echo“设置分页关闭”>>trace.gdb #设置断点以读取var地址 echo“break main”>>trace.gdb #运行调试器 echo“run”>>trace
gdb
脚本来观察变量的变化,使用awatch
:
#/bin/bash
#编撰
gcc-Wall-pedantic-g-o demo.c
#编译错误时退出
如果[$?-ne 0];然后
出口
fi
#用标题覆盖trace.gdb的内容
echo“#Watch var”>trace.gdb
#不要每次分页时都停止
echo“设置分页关闭”>>trace.gdb
#设置断点以读取var地址
echo“break main”>>trace.gdb
#运行调试器
echo“run”>>trace.gdb
#设定观察点
echo“awatch var”>>trace.gdb
#不要在每个观察点停止(只显示跟踪)
echo“commands”>>trace.gdb
echo“continue”>>trace.gdb
echo“end”>>trace.gdb
#开始监控
echo“continue”>>trace.gdb
#退出调试器
echo“quit”>>trace.gdb
#运行生成的脚本
gdb-quiet-command=trace.gdb demo
该方案:
/* demo.c */
#include <stdio.h>
int main(void)
{
int var = 0;
for (int i = 0; i < 5; i++)
{
var++;
}
printf("%d\n", var);
return 0;
}
然后运行相同的脚本,gdb
开始打印错误的值:
Breakpoint 1, main () at demo.c:6
6 {
Hardware access (read/write) watchpoint 2: var
Hardware access (read/write) watchpoint 2: var
Value = 0
main () at demo.c:9
9 srand((unsigned)time(NULL));
Hardware access (read/write) watchpoint 2: var
Old value = 0
New value = 32015002
0x00005555555551f8 in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Value = 32015002
0x00005555555551fb in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Old value = 32015002
New value = 7
main () at demo.c:10
10 for (int i = 0; i < 5; i++)
Hardware access (read/write) watchpoint 2: var
Old value = 7
New value = 84992124
0x00005555555551f8 in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Value = 84992124
0x00005555555551fb in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Old value = 84992124
New value = 6
main () at demo.c:10
10 for (int i = 0; i < 5; i++)
Hardware access (read/write) watchpoint 2: var
Old value = 6
New value = 55442740
0x00005555555551f8 in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Value = 55442740
0x00005555555551fb in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Old value = 55442740
New value = 0
main () at demo.c:10
10 for (int i = 0; i < 5; i++)
Hardware access (read/write) watchpoint 2: var
Old value = 0
New value = 208731384
0x00005555555551f8 in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Value = 208731384
0x00005555555551fb in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Old value = 208731384
New value = 3
main () at demo.c:10
10 for (int i = 0; i < 5; i++)
Hardware access (read/write) watchpoint 2: var
Old value = 3
New value = 114916873
0x00005555555551f8 in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Value = 114916873
0x00005555555551fb in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Old value = 114916873
New value = 9
main () at demo.c:10
10 for (int i = 0; i < 5; i++)
Hardware access (read/write) watchpoint 2: var
Value = 9
0x0000555555555216 in main () at demo.c:14
14 printf("%d\n", var);
9
demo.c:6处的断点1,main()
6 {
硬件访问(读/写)观察点2:var
硬件访问(读/写)观察点2:var
值=0
main()位于demo.c:9
9 srand((无符号)时间(NULL));
硬件访问(读/写)观察点2:var
旧值=0
新值=32015002
demo.c:12处的main()中的0x000055551F8
12 var=rand()%10;
硬件访问(读/写)观察点2:var
值=32015002
demo.c:12处的main()中的0x000055551fb
12 var=rand()%10;
硬件访问(读/写)观察点2:var
旧值=32015002
新值=7
main()位于demo.c:10
10表示(int i=0;i<5;i++)
硬件访问(读/写)观察点2:var
旧值=7
新值=84992124
demo.c:12处的main()中的0x000055551F8
12 var=rand()%10;
硬件访问(读/写)观察点2:var
值=84992124
demo.c:12处的main()中的0x000055551fb
12 var=rand()%10;
硬件访问(读/写)观察点2:var
旧值=84992124
新值=6
main()位于demo.c:10
10表示(int i=0;i<5;i++)
硬件访问(读/写)观察点2:var
旧值=6
新值=55442740
demo.c:12处的main()中的0x000055551F8
12 var=rand()%10;
硬件访问(读/写)观察点2:var
值=55442740
demo.c:12处的main()中的0x000055551fb
12 var=rand()%10;
硬件访问(读/写)观察点2:var
旧值=55442740
新值=0
main()位于demo.c:10
10表示(int i=0;i<5;i++)
硬件访问(读/写)观察点2:var
旧值=0
新值=208731384
demo.c:12处的main()中的0x000055551F8
12 var=rand()%10;
硬件访问(读/写)观察点2:var
值=208731384
demo.c:12处的main()中的0x000055551fb
12 var=rand()%10;
硬件访问(读/写)观察点2:var
旧值=208731384
新值=3
main()位于demo.c:10
10表示(int i=0;i<5;i++)
硬件访问(读/写)观察点2:var
旧值=3
新值=114916873
demo.c:12处的main()中的0x000055551F8
12 var=rand()%10;
硬件访问(读/写)观察点2:var
值=114916873
demo.c:12处的main()中的0x000055551fb
12 var=rand()%10;
硬件访问(读/写)观察点2:var
旧值=114916873
新值=9
main()位于demo.c:10
10表示(int i=0;i<5;i++)
硬件访问(读/写)观察点2:var
值=9
demo.c:14处的main()中的0x00005555216
14 printf(“%d\n”,var);
9
我读过这篇文章:并用-fvar跟踪编译了它,但它没有帮助
为什么未优化的gcc程序集会出现这种行为
jmp .L2
.L3:
call rand
movl %eax, %edx
movslq %edx, %rax
imulq $1717986919, %rax, %rax
shrq $32, %rax
sarl $2, %eax
movl %edx, %ecx
sarl $31, %ecx
subl %ecx, %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %ecx
movl %ecx, %eax
sall $2, %eax
addl %ecx, %eax
addl %eax, %eax
subl %eax, %edx
movl %edx, -4(%rbp)
addl $1, -8(%rbp)
.L2:
cmpl $9, -8(%rbp)
jle .L3
你似乎在加热-4(%rbp)
。所以有movl%eax,-4(%rbp)
放一个“大数字”,然后读入movl-4(%rbp),%ecx
,然后是movl%edx,-4(%rbp)
其中放置了%10
的结果。因此,您可以从计算中间看到一些数字。例如,一个循环对应于:
New value = 32015002
0x00005555555551f8 in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Value = 32015002
0x00005555555551fb in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Old value = 32015002
New value = 7
main () at demo.c:10
10 for (int i = 0; i < 5; i++)
Hardware access (read/write) watchpoint 2: var
新值=32015002
demo.c:12处的main()中的0x000055551F8
12 var=rand()%10;
硬件访问(读/写)观察点2:var
值=32015002
demo.c:12处的main()中的0x000055551fb
12 var=rand()%10;
硬件访问(读/写)观察点2:var
旧值=32015002
新值=7
main()位于demo.c:10
10表示(int i=0;i<5;i++)
硬件访问(读/写)观察点2:var
为什么使用rand()会出现这种行为?
检查汇编代码。可能是编译器在循环后优化了%10
操作。@编辑否,值有意义。第一个变量与rand()的结果相关联
Value=208731384
然后计算%10
旧值=208731384新值=3
。编译器有效地执行var=rand();var%=10
…或其他各种与优化相关的效果。如果使用-O0
编译,意外行为很可能会消失。调试优化代码时会出现各种各样的奇怪现象。@JohnBollinger谢谢,与-O0
@KamilCuk相同的输出这很有意义,usingint r=rand()%10;var=r;
输出是正确的,这是汇编代码:,但我不善于阅读汇编:(非常感谢您的帮助!@KamilCuk,我想我可以确认您的观点:包括
并使用var=rand()将var
声明为原子变量=0;
)%10;
输出也正确,请随时将您的评论作为答案发布,我将接受。
jmp .L2
.L3:
call rand
movl %eax, %edx
movslq %edx, %rax
imulq $1717986919, %rax, %rax
shrq $32, %rax
sarl $2, %eax
movl %edx, %ecx
sarl $31, %ecx
subl %ecx, %eax
movl %eax, -4(%rbp)
movl -4(%rbp), %ecx
movl %ecx, %eax
sall $2, %eax
addl %ecx, %eax
addl %eax, %eax
subl %eax, %edx
movl %edx, -4(%rbp)
addl $1, -8(%rbp)
.L2:
cmpl $9, -8(%rbp)
jle .L3
New value = 32015002
0x00005555555551f8 in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Value = 32015002
0x00005555555551fb in main () at demo.c:12
12 var = rand() % 10;
Hardware access (read/write) watchpoint 2: var
Old value = 32015002
New value = 7
main () at demo.c:10
10 for (int i = 0; i < 5; i++)
Hardware access (read/write) watchpoint 2: var