c - 如何通过优化标志追踪代码行为不同的原因

标签 c gcc optimization valgrind

所以我有一些复杂的 C 代码,可以通过纠错对位数组进行编码和解码。该代码基于 this ,并进行了修补以满足我的需求(因此它的功能实际上与链接代码不同,除了其核心之外)。

关闭优化后,我得到了我期望的输出。通过完全优化(即在 gcc 编译期间提供 -O3),代码的行为有所不同。

我正在尝试找出我应该寻找什么来追踪这个问题;就像在开始在代码中的任何位置添加 printf 之前我可以寻找优化所做的一些明显的事情,以查看哪些行的输出在优化之间有所不同。

我认为,一个线索是,当我在没有优化的情况下通过 valgrind 运行代码时,我没有收到任何错误或警告:

==5112== Memcheck, a memory error detector
==5112== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5112== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==5112== Command: ./a.out
==5112== 
!!!!! decode ret = 0 (my output)
Nid decoded = 0010100100111010101110101001001110111110110000100110101000101011 (my output)
==5112== 
==5112== HEAP SUMMARY:
==5112==     in use at exit: 0 bytes in 0 blocks
==5112==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==5112== 
==5112== All heap blocks were freed -- no leaks are possible
==5112== 
==5112== For counts of detected and suppressed errors, rerun with: -v
==5112== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

启用优化并 --track-origins=yes 后,valgrind 会报告以下内容:

==5506== Memcheck, a memory error detector
==5506== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5506== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==5506== Command: ./a.out
==5506== 
==5506== Conditional jump or move depends on uninitialised value(s)
==5506==    at 0x400DC1: bch_decode (in /home/directory/bch/a.out)
==5506==    by 0x4005CD: main (in /home/directory/bch/a.out)
==5506==  Uninitialised value was created by a stack allocation
==5506==    at 0x40094B: bch_decode (in /home/directory/bch/a.out)
==5506== 
==5506== Use of uninitialised value of size 8
==5506==    at 0x400DC3: bch_decode (in /home/directory/bch/a.out)
==5506==    by 0x4005CD: main (in /home/directory/bch/a.out)
==5506==  Uninitialised value was created by a stack allocation
==5506==    at 0x40094B: bch_decode (in /home/directory/bch/a.out)
==5506== 
!!!!! decode ret = -1
Nid decoded = 0010100100111010101110101001001110111110110000100010101000101011
==5506== 
==5506== HEAP SUMMARY:
==5506==     in use at exit: 0 bytes in 0 blocks
==5506==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==5506== 
==5506== All heap blocks were freed -- no leaks are possible
==5506== 
==5506== For counts of detected and suppressed errors, rerun with: -v
==5506== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

但是,通过优化,我认为 Valgrind 无法告诉我具体的行号或发生这种情况的变量。即使我使用 GDB 单步执行代码,由于优化也很难确定这一点。

有没有一种方法可以解决这个问题,也许/模拟/优化的行为,但在调试信息中保留正确的行号和变量名称(从我迄今为止阅读的所有内容来看,这不太可能)。

任何能够插入这一进程的帮助,哪怕是一点点,我们都将不胜感激。

最佳答案

valgrind 告诉您有未初始化的变量:

==5506== Conditional jump or move depends on uninitialised value(s)
==5506==    at 0x400DC1: bch_decode (in /home/directory/bch/a.out)
==5506==    by 0x4005CD: main (in /home/directory/bch/a.out)
==5506==  Uninitialised value was created by a stack allocation
==5506==    at 0x40094B: bch_decode (in /home/directory/bch/a.out)
==5506== 
==5506== Use of uninitialised value of size 8
==5506==    at 0x400DC3: bch_decode (in /home/directory/bch/a.out)
==5506==    by 0x4005CD: main (in /home/directory/bch/a.out)
==5506==  Uninitialised value was created by a stack allocation
==5506==    at 0x40094B: bch_decode (in /home/directory/bch/a.out)

使用 -g 标志重新编译并重新链接代码,以查看 valgrind 输出中的行号。

关于c - 如何通过优化标志追踪代码行为不同的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34360572/

相关文章:

c - 将地址传递给指针函数

c - 重新定义函数 lin libC

linux - 交叉编译 node.js 到 MIPS 24Kc V5.0

optimization - `USE` 对性能的影响

MySQL 表 - 性能、索引数量

c++ - 同时进行优化和可测试性——如何将代码分解成更小的单元

c - 字符数组以何种方式在本地分配内存?

c - 模拟 C 中各种结构的 array_pop

c++ - ms-extensions 标志对 gcc 有什么作用?

c - GCC:允许 C99 中的重载函数