为什么GDB在此说明中不违反?

问题描述 投票:0回答:1
是宏,这应该是编译时内存分配,而GDB不会破坏并跳过线路。

#define BUFFER_SIZE 50 int main(){ const int sz = BUFFER_SIZE; char buffer[BUFFER_SIZE]; // does not break when a breakpoint is specified here }

这是一个运行时分配,GDB确实会破裂。

#define BUFFER_SIZE 50 int main(){ const int sz = BUFFER_SIZE; char buffer[sz]; // it does break here }
我认为这是因为编译时评估的指令无法进行调试,因为GDB在运行时进行调试,是正确的还是有其他解释?

Tl;dr

您只能在具有机器指令的行上设置一个断点。
c gdb
1个回答
0
投票
数组定义作为局部变量仅需要指令是在运行时构建的VLA时。

以下实验是使用我手头的64位Windows 10机器13.2.0进行的MINGW进行的。

I与选项汇编。当然,由于未使用的变量,编译器给了我警告。

通过可执行文件中的

-Wall -pedantic -g

生成了组装列表。

不优化为C

没有优化(像您一样),编译器会生成不同的代码。
在第一个程序中,您的数组大小具有编译时常数。因此,编译器直接在分配的局部变量的堆栈空间中包含数组。因此,没有关于定义线的指示。

objdump -dS

在第二个程序中,由于变量,编译器会看到VLA。它为分配生成指令,因此您可以设置一个断点。 (旁注:默认情况下,编译器检查堆栈是否有数组的空间。)

-O0

无需优化为C ++

当汇编为C ++时,第二个程序的常数变量在语义上是编译时常数,因此两个可执行文件之间没有区别。
在两种情况下都无法设置断点。

0000000140001450 <main>: #define BUFFER_SIZE 50 int main(){ 140001450: 55 push %rbp 140001451: 48 89 e5 mov %rsp,%rbp 140001454: 48 83 ec 60 sub $0x60,%rsp 140001458: e8 c3 00 00 00 call 140001520 <__main> const int sz = BUFFER_SIZE; 14000145d: c7 45 fc 32 00 00 00 movl $0x32,-0x4(%rbp) 140001464: b8 00 00 00 00 mov $0x0,%eax char buffer[BUFFER_SIZE]; // does not break when a breakpoint is specified here } 140001469: 48 83 c4 60 add $0x60,%rsp 14000146d: 5d pop %rbp 14000146e: c3 ret

0000000140001450 <main>: #define BUFFER_SIZE 50 int main(){ 140001450: 55 push %rbp 140001451: 48 89 e5 mov %rsp,%rbp 140001454: 48 83 ec 40 sub $0x40,%rsp 140001458: e8 03 01 00 00 call 140001560 <__main> 14000145d: 48 89 e0 mov %rsp,%rax 140001460: 48 89 c2 mov %rax,%rdx const int sz = BUFFER_SIZE; 140001463: c7 45 fc 32 00 00 00 movl $0x32,-0x4(%rbp) char buffer[sz]; // it does break here 14000146a: 8b 45 fc mov -0x4(%rbp),%eax 14000146d: 48 98 cltq 14000146f: 48 83 e8 01 sub $0x1,%rax 140001473: 48 89 45 f0 mov %rax,-0x10(%rbp) 140001477: 8b 45 fc mov -0x4(%rbp),%eax 14000147a: 48 98 cltq 14000147c: 48 83 c0 0f add $0xf,%rax 140001480: 48 c1 e8 04 shr $0x4,%rax 140001484: 48 c1 e0 04 shl $0x4,%rax 140001488: e8 a3 10 00 00 call 140002530 <___chkstk_ms> 14000148d: 48 29 c4 sub %rax,%rsp 140001490: 48 8d 44 24 20 lea 0x20(%rsp),%rax 140001495: 48 83 c0 00 add $0x0,%rax 140001499: 48 89 45 e8 mov %rax,-0x18(%rbp) 14000149d: 48 89 d4 mov %rdx,%rsp 1400014a0: b8 00 00 00 00 mov $0x0,%eax } 1400014a5: 48 89 ec mov %rbp,%rsp 1400014a8: 5d pop %rbp 1400014a9: c3 ret

用优化为C
最终,我用

sz

编译了两个程序,该程序产生了相同的机器代码。编译器发现变量未使用并删除。因此,您无法设置断点。

0000000140001450 <main>: #define BUFFER_SIZE 50 int main(){ 140001450: 55 push %rbp 140001451: 48 89 e5 mov %rsp,%rbp 140001454: 48 83 ec 60 sub $0x60,%rsp 140001458: e8 c3 00 00 00 call 140001520 <__main> const int sz = BUFFER_SIZE; 14000145d: c7 45 fc 32 00 00 00 movl $0x32,-0x4(%rbp) char buffer[BUFFER_SIZE]; // does not break when a breakpoint is specified here } 140001464: b8 00 00 00 00 mov $0x0,%eax 140001469: 48 83 c4 60 add $0x60,%rsp 14000146d: 5d pop %rbp 14000146e: c3 ret
0000000140001450 <main>:
#define BUFFER_SIZE 50
int main(){
   140001450:   55                      push   %rbp
   140001451:   48 89 e5                mov    %rsp,%rbp
   140001454:   48 83 ec 60             sub    $0x60,%rsp
   140001458:   e8 c3 00 00 00          call   140001520 <__main>
  const int sz = BUFFER_SIZE;
   14000145d:   c7 45 fc 32 00 00 00    movl   $0x32,-0x4(%rbp)
  char buffer[sz]; // it does break here
}
   140001464:   b8 00 00 00 00          mov    $0x0,%eax
   140001469:   48 83 c4 60             add    $0x60,%rsp
   14000146d:   5d                      pop    %rbp
   14000146e:   c3                      ret


最新问题
© www.soinside.com 2019 - 2025. All rights reserved.