【问题标题】:Trace changes to variables automatically自动跟踪变量的变化
【发布时间】:2010-11-05 08:34:53
【问题描述】:

我正在调试一个 C 程序(Linux 中的 GCC 和 GDB 以及 Windows 中的 Visual Studio),它在两种不同的体系结构上给出不同的结果。我想通过跟踪变量中存储的值的变化来比较每个架构的执行情况,以找出差异。

文件 main.c,第 234 行。变量 A 从 34 更改为 23 文件 main.c,第 236 行。变量 B 从 0 更改为 2 ...... 等等

是否可以指示编译器对此进行检测,而无需手动在源代码中添加printf 语句?

【问题讨论】:

  • 这不是观察点的用途吗?
  • 我不知道可能导致错误的变量是什么。观察点只有在您知道这一点时才有用
  • 如果你不知道你在找什么,那么阅读这个“变量更改日志”会比简单地在调试器中单步执行代码并查看变量更容易/更快吗?点?
  • 如果程序在每次运行时的行为都完全相同,您可以使用二进制搜索来查找问题:在中间放置一个断点,比较所有变量 -> 如果它们相同,请检查第二半,否则,检查第一半。重复直到找到产生不同结果的第一行。您说您的程序只有 10 kLOC,这意味着 15-16 个中断/比较周期。
  • 如果这是您从老板那里得到的代码,并且只需在不进行多次修改的情况下对其进行修复,您就不能告诉老板“这是错误的”:-P

标签: c debugging compiler-construction


【解决方案1】:

我会编写一个脚本来自动引导调试器。我不知道 expect 在 Windows 上是否可用(可能是),但它是编写自动驾驶交互式工具的脚本的好工具。该脚本将类似于:

#!/usr/bin/expect
set progname [lindex $argv 0]
spawn gdb $progname
expect "(gdb)"
send "break main\n"
expect "(gdb)"
send "run\n"
while 1 {
    expect {
    "(gdb)" {
        send "info locals\n"
        expect "(gdb)"
        send "next\n"
    }

"Program exited normally" {
    exit;
}
}

}

我会将“main”更改为您认为程序出错的函数。您还可以插入任何其他您想要的调试器命令,例如在打印变量之前打印出您所在的行;在这里,我使用“info locals”打印出所有本地值。显然,您需要将此输出保存到文件中以供分析。 Expect 非常容易学习,语法全部基于 tcl。

【讨论】:

  • 我应该注意到,有许多语言的接口,如果你熟悉 perl、python 等,那可能会更容易
  • 你好,所有的答案真的很好很有趣,但你的答案是最简单实用的,我最后试试这个
【解决方案2】:

在隐式解决方案中需要考虑几个因素:

  • C 几乎不知道类型。例如,如果您使用@Jens Gustedt 对检测函数的建议,您仍然存在确定您在堆栈上查看的确切内容以及如何正确打印出值的问题。 IIRC,检测函数不会为您提供即将到来的函数的原型,也不会提供带有指向这些值的指针的方便结构。这将更类似于 C++ 模板。您必须编写一个了解所有函数原型的进入/退出函数,并了解变量的精确调用约定和打包安排。
  • 您需要使用调试符号进行编译,以确定哪些内存与您的代码中定义的变量相关联,以及修改这些变量的时间。
  • 更复杂的类型没有标准的打印方式(例如结构),即使在 C++ 中也是如此。您需要具有符合某种接口的打印功能。
  • 不确定长度的指针和数组将很难处理。您需要测试 NULL 指针,并提前知道数组大小以正确打印它们的值。

我在我正在处理的existing project 中尝试了类似于您的“函数入口处的 printf”的东西。这对important functions 很有用,但我从asserting values are in the expected ranges at function entry 中得到了更多的信息并退出。这是日志headersource,它们演示了如何大大简化围绕手动跟踪的行、函数和其他有用信息的打印。您会注意到我的许多类型都有相应的*_valid() 函数,以及围绕它们使用的断言。一旦我的程序跑出轨道(我向你保证在调试过程中非常频繁),断言就会触发,我可以通过堆栈跟踪分析情况。

您还可能会发现 this answer 对于单独使用 C 做这些事情的困难以及如何使用宏来解决它很有用。

如果您需要隐式执行此操作,最好的选择是通过 GDB,大概您可以write scripts 分析每条指令后的更改,并使用-g 提供的调试信息智能地确定和打印类型。

【讨论】:

  • 不幸的是,原始问题描述的那种错误可能是由于未初始化的变量和类似的问题,这些问题会在仪器(或不同的调试/优化级别或编译器版本,...)
【解决方案3】:

Valgrind 可以自动跟踪所有商店,尽管标准工具不容易提供明确的跟踪。您必须编写自己的 valgrind 工具,例如通过修改 cachegrind,跟踪所有 Ist_Store 指令。

唉,valgrind 不能在 Windows 上运行。

【讨论】:

  • 唉,确实有很多很棒的工具不能在 Windows 上运行:@
  • windows 本身不能在 windows 上运行:-P。你能指出一些关于如何按照你提到的方式修改缓存研磨的链接吗?谢谢
【解决方案4】:

gdb 和 Visual Studio 的调试器都支持 watch 变量。这就像一个断点,而不是代码中的一个位置,当变量的值更改时,程序会中断。如果将值更改为与已有值完全相同的值,您可能会发现它们的行为并不完全相同(不确定是否有任何差异,但可能存在差异)。

如果您正在观察局部变量,您可能会发现两个调试器的行为存在差异的另一个地方。一个调试器可能会忘记返回的函数中的任何监视变量,而另一个调试器可能每次都重新监视它们,而另一个调试器可能最终只是监视实际的内存位置,而不关心该内存已被重新用于什么用途。我不确定这些调试器在这方面是如何工作的,因为我没有观察局部变量的习惯(我不确定我是否看过局部变量)。

您可能想要做的是在初始化这些变量的位置周围设置一个断点,逐步完成初始化,然后对变量设置一个监视并让程序运行。您可以记录更改(手动或{至少使用 gdb} 脚本)并查看两个程序何时出现行为差异。

您可能会发现某个类型的大小与另一个不同,您正在使用未初始化的内存(并且未初始化的内存在两个系统上的设置不同),或者某些数据结构填充可能正在改变某些东西.如果它更复杂,那不是像 API 函数出错并且你没有检查它,或者一个或两个编译器给你的一些警告你正在忽略,那么它可能很难找到。

您应该确保关闭所有优化,除非问题仅在优化打开时出现。

可能会对您有很大帮助的方法是尝试在每台机器上对程序的各个部分进行单元测试。发现和理解小问题的行为差异要比大问题容易得多。

【讨论】:

    【解决方案5】:

    显而易见的问题是要问你的程序(以及它调用的所有库)是否真的独立于架构,或者甚至是确定性的(例如,你可能有一个不稳定的排序,甚至某个地方的线程),或者如果你只是在某个地方有一个未初始化的变量。

    假设您认为您的程序是完全确定性的,并且您确实希望对每个分配进行数据跟踪,实现此目的的一种方法是使用 program transformation system。这样的工具使用目标语言(在本例中为 C)的表面语法接受“如果你看到这个,用那个替换它”模式。您使用转换规则来检测您的程序,以自动找到需要检测的所有位置并将其插入到那里,编译并运行检测的程序,然后在获得跟踪后丢弃检测的版本。

    我们的DMS Software Reengineering Toolkit 可以做到这一点。您要做的是用 assignment 和 printf 的组合替换每个分配。 实现此目的的 DMS 重写规则是:

            rule insert_tracing_printfs(l: lhs, e: expression): expression -> expression =
               " \lhs=\e " -> "print_and_assign_int(\tostring\(\lhs\),&\lhs,\e)" if int_type(lhs);
    

    基本规则格式是ifyouseethis -> replacebythis if somecondition。引号实际上是元引号,并使 C 语法能够嵌入到规则语言中。 \ 是对 C 语法的一种转义 回到规则语言。

    这些规则对 DMS 生成的抽象语法树进行操作,作为解析(预处理的)C 源代码的结果。对于所有合法形式的 lhse,此特定规则准确地匹配源代码的精确语法 lhs=*e*。当它找到这样的匹配时,它会通过函数调用替换分配 这恰好完成了分配并打印出您的跟踪值。

    \tostring 函数获取 lhs 树并生成与原始文本对应的源文本 表达;这可以通过用于漂亮打印 AST 的 DMS API 轻松完成。 int_type 函数询问 DMS 生成的符号表以确定 lhs 的类型是否为 int

    对于要打印的每种数据类型,您都需要一个规则。您还需要为程序使用的每种赋值语法(例如,“=”、“+=”、“%=”...)制定规则。因此,基本数据类型和少量赋值语法类型表明您需要 1-2 打这样的规则。

    你还需要对应的C函数来匹配各种数据类型:

            int print_and_assign_int(char* s, int* t, int v)
            { printf("Integer variable %s changes from %d to %d\n",s,*t,v);
              *t=v;
              return v;
            }
    

    (如果您也需要文件和行号,您可以使用 C 预处理器宏将它们作为额外参数添加到打印函数中,用于文件和行号。)

    对于像这样的 C 语句:

               if (x=getc())
                  { y="abc";
                    p=&y;
                  }
    

    以这种方式完成的一组重写规则会自动产生如下内容:

              if (print_and_assign_char("x", &x,getc()))
                 { print_and_assign_charstar("y",&y,"abc");
                   print_and_assign_ptrtocharstar("p",&p,&y);
                 }
    

    您必须决定如何打印分配的指针值,因为您必须假设它们没有等效的地址,因此您基本上必须打印指针选择的值。每当您有 void* 时,这都会给您带来麻烦;但是您可以打印出您对 void* 变量的了解,例如,is 是否为 NULL,这仍然是有用的跟踪数据。

    如果您经常进行这种调试,这一切都值得。恕我直言,您最好还是硬着头皮调试解决方案,因为我希望您会对某些架构依赖性感到惊讶。

    【讨论】:

      【解决方案6】:

      如果你想要跨平台,printf 是你的朋友。使用 grep 进行一些操作将找到变量被分配到的位置。除此之外,我认为您最好将精力花在弄清楚如何缩短编辑/编译*2/run_tests*2/diff 周期并考虑在哪里进行二进制拆分。

      在回来的时候,我或多或少地有同样的问题要解决,但中间有一个不完整的语言翻译器增加了复杂性。能够同时运行两个版本并快速区分输出使其成为一个非常合理的问题。

      【讨论】:

        【解决方案7】:

        你可以让 gdb 在某些指令修改你的变量时中断。 IIRC 命令是“观察”。例如。 '看 A',或'看 *(int*)0x123456'

        当有人阅读它时,你甚至可以用“rwatch”告诉它中断。

        【讨论】:

        • 我知道,但这只是当您知道“要遵循”的变量时。我只想在屏幕上转储所有更改,因此我比较了两种架构的结果,并确切知道两个程序何时开始分歧
        【解决方案8】:

        您可以告诉 gcc 检测函数调用:-finstrument-functions。这不会让您了解分配的粒度,但如果您将一些基本功能打包到 inline 函数中,则关闭。

        【讨论】:

          【解决方案9】:

          我认为ctrace 程序可能是您所追求的;它在 AT&T Unix 中可用(早在 AT&T 拥有 Unix 的时代),但 URL 是 Sun 手册页。因此,您可能可以在其他专有版本的 Unix(AIX、HP-UX、SCO)上找到它;不清楚是否有适用于 Linux 的版本。

          SourceForge 的 CTrace 库根本不是一回事。

          【讨论】:

          • 可能也可以在 UWIN 中找到 ctrace,这将为您提供 windows 中的 posix 环境。在这里找到UWIN:www2.research.att.com/sw/tools/uwin
          • 知道我以前在 AT&T 开源存储库的某个地方看到过 ctrace,但是……即使经过将近一个小时的查找,我也找不到它。对不起。
          【解决方案10】:

          如果你知道你感兴趣的变量变化的行,那么你可以使用断点命令做一个简单的跟踪:

          例子:

          #include <iostream>
          
          int main(int, char **)
          {
            for(int i = 0; i < 100; ++i)
            {
              std::cout << i << std::endl;
            }
          
            return 0;
          }
          

          当你编译这个程序时

          c++ -g -o t1 t1.cpp
          

          那么你可以像这样使用断点命令:

          break 7
          commands
          print i
          continue
          end
          

          生成一个简单的跟踪。这也应该适用于观察点(当变量改变状态时触发的断点)。

          这是一个示例 gdb 会话的日志:

          $ gdb t1
          GNU gdb (GDB) 7.1-ubuntu
          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-linux-gnu".                                                               
          For bug reporting instructions, please see:                                                                  
          <http://www.gnu.org/software/gdb/bugs/>...                                                                   
          Reading symbols from /tmp/t1...done.                                                                         
          (gdb) break 7                                                                                                
          Breakpoint 1 at 0x40087c: file t1.cpp, line 7.
          (gdb) commands
          Type commands for when breakpoint 1 is hit, one per line.
          End with a line saying just "end".
          >print i
          >continue
          >end
          (gdb) set pagination off
          (gdb) r
          Starting program: /tmp/t1 
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $1 = 0
          0
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $2 = 1
          1
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $3 = 2
          2
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $4 = 3
          3
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $5 = 4
          4
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $6 = 5
          5
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $7 = 6
          6
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $8 = 7
          7
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $9 = 8
          8
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $10 = 9
          9
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $11 = 10
          10
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $12 = 11
          11
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $13 = 12
          12
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $14 = 13
          13
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $15 = 14
          14
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $16 = 15
          15
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $17 = 16
          16
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $18 = 17
          17
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $19 = 18
          18
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $20 = 19
          19
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $21 = 20
          20
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $22 = 21
          21
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $23 = 22
          22
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $24 = 23
          23
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $25 = 24
          24
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $26 = 25
          25
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $27 = 26
          26
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $28 = 27
          27
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $29 = 28
          28
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $30 = 29
          29
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $31 = 30
          30
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $32 = 31
          31
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $33 = 32
          32
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $34 = 33
          33
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $35 = 34
          34
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $36 = 35
          35
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $37 = 36
          36
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $38 = 37
          37
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $39 = 38
          38
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $40 = 39
          39
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $41 = 40
          40
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $42 = 41
          41
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $43 = 42
          42
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $44 = 43
          43
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $45 = 44
          44
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $46 = 45
          45
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $47 = 46
          46
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $48 = 47
          47
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $49 = 48
          48
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $50 = 49
          49
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $51 = 50
          50
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $52 = 51
          51
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $53 = 52
          52
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $54 = 53
          53
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $55 = 54
          54
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $56 = 55
          55
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $57 = 56
          56
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $58 = 57
          57
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $59 = 58
          58
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $60 = 59
          59
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $61 = 60
          60
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $62 = 61
          61
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $63 = 62
          62
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $64 = 63
          63
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $65 = 64
          64
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $66 = 65
          65
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $67 = 66
          66
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $68 = 67
          67
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $69 = 68
          68
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $70 = 69
          69
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $71 = 70
          70
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $72 = 71
          71
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $73 = 72
          72
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $74 = 73
          73
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $75 = 74
          74
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $76 = 75
          75
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $77 = 76
          76
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $78 = 77
          77
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $79 = 78
          78
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $80 = 79
          79
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $81 = 80
          80
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $82 = 81
          81
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $83 = 82
          82
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $84 = 83
          83
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $85 = 84
          84
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $86 = 85
          85
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $87 = 86
          86
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $88 = 87
          87
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $89 = 88
          88
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $90 = 89
          89
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $91 = 90
          90
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $92 = 91
          91
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $93 = 92
          92
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $94 = 93
          93
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $95 = 94
          94
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $96 = 95
          95
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $97 = 96
          96
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $98 = 97
          97
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $99 = 98
          98
          
          Breakpoint 1, main () at t1.cpp:7
          7           std::cout << i << std::endl;
          $100 = 99
          99
          
          Program exited normally.
          (gdb) q
          

          【讨论】:

            【解决方案11】:

            首先,我假设您实际上在这两种情况下都使用了相同的代码。否则,开始寻找代码的不同之处。

            如果您的程序在不同的架构上给出不同的结果,那么您可能没有以正确的方式处理某些事情。 我要做的第一件事是打开所有可能的编译器警告并注意它们。

            如果没有任何结果,我会尝试使用静态代码分析工具。我用过coverity(商业产品),但也有others。 这些工具有时会帮助您找到编译器没有发现的程序中的错误。

            当这些自动化选项用尽时,我可能会尝试比较整个程序中的所有变量。根据您的程序大小,这可能非常耗时。

            【讨论】:

              猜你喜欢
              • 2015-05-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-09-17
              • 2013-06-04
              • 1970-01-01
              • 2011-06-15
              • 1970-01-01
              相关资源
              最近更新 更多