小编Sho*_*ker的帖子

两次 GCC 编译相同的输入,生成两个不同的代码(第二个错误)

有时我在使用 GCC(4.6.4,Ubuntu 12.04)时遇到一个奇怪的问题,我用它来编译一个巨大的项目(数百个文件和数十万行代码),但我最近发现了一些东西。在某些编译之后(似乎是随机发生的),我得到一段特定的代码以不同的方式和错误地编译,导致我的代码中出现未定义的行为:

class someDerivedClass : public someBaseClass
{
    public:
        struct anotherDerived : public anoterBaseClass
        {
            void SomeMethod()
            {
                someMember->someSetter(2);
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

其中“someSetter”定义为:

void someSetter(varType varName) { someOtherMember = varName; }
Run Code Online (Sandbox Code Playgroud)

通常,SomeMethod() 被编译为:

00000000019fd910  mov 0x20(%rdi),%rax 
00000000019fd914  movl $0x2,0x278c(%rax) 
00000000019fd91e  retq  
Run Code Online (Sandbox Code Playgroud)

但有时它会(错误地)编译为:

000000000196e4ee  mov 0x20(%rdi),%rax 
000000000196e4f2  movl $0x2,0x27d4(%rax) 
000000000196e4fc  retq  
Run Code Online (Sandbox Code Playgroud)

setter 似乎被内联了,可能是因为编译标志 -O2:

-std=c++11 -m64 -O2 -ggdb3 -pipe -Wliteral-suffix -fpermissive -fno-fast-math -fno-strength-reduce -fno-delete-null-pointer-checks -fno-strict-aliasing
Run Code Online (Sandbox Code Playgroud)

但这不是问题。真正的问题是成员someOtherMember的偏移量,0x278c是正确的(第一种情况),但0x27d4不正确(第二种情况),这显然最终会修改类中完全不同的成员。为什么会发生这种情况?我缺少什么?(另外,我不知道我可以发布哪些其他相关信息,所以询问)。请记住,当再次编译项目(完全重新编译或仅编译修改后的文件)而不修改受影响的文件(或具有所使用的类的文件)时,会发生这种情况。例如,仅在完全不相关的文件中的某处添加一个简单的 printf() 可能会触发此行为或使其在发生时消失。我应该把这归咎于 -O2 吗?如果没有优化标志,我无法重现它,因为这是完全随机发生的。我正在使用make -j …

c++ gcc

5
推荐指数
1
解决办法
395
查看次数

性能调用图中的源行号?

我通常perf record -a --call-graph dwarf -p XXX sleep 1先记录一些函数调用,然后perf report查看该数据,但是如果我还能看到源代码行号以准确知道每个函数调用的位置,那将非常有帮助。例如:

-   4.18%  testbinary  testbinary                [.] malloc 
   - malloc 
      - 99.57% operator new(unsigned long)
         + 7.28% MyFunction()
Run Code Online (Sandbox Code Playgroud)

我想知道调用的确切MyFunction()位置new operators(不用看整个函数源代码就可以猜测)

PS:二进制与 -m64 -O2 -ggdb3

linux perf

5
推荐指数
2
解决办法
2043
查看次数

GDB自杀(突然杀死调试进程)

我正在通过 GDB(版本 7.12,Ubuntu 14.04)运行一个非常大的应用程序(二进制文件有 2GB,主要是因为调试符号),因此我可以捕获所有崩溃并具有完整的回溯 + 核心转储: ulimit -c unlimited 以及bt / bt full / info thread / generate-core-file崩溃后。

然而,我很少遇到一些奇怪的行为:应用程序立即关闭并Program terminated with signal SIGKILL, Killed.记录在日志中,但是我 100% 肯定系统中没有其他任何东西会杀死它,对此负责的是 GDB。发生这种情况时,它不会生成任何回溯/核心转储/等。

据我所知,到目前为止,这种情况发生在正常运行时间较长(1 天)的情况下。每当正常运行时间约为 1 天时发生正常崩溃(我不是在谈论终止情况,而是正常崩溃)并且 GDB 生成回溯 + 核心转储,核心转储大小约为 100GB。所以现在唯一可以假设的是 GDB 消耗了太多内存来处理它。不幸的是,我不知道发生这种情况时的确切内存使用情况(因为这是意外的),但交换文件几乎是空的,这很可能意味着它并没有真正耗尽内存。

关于如何调试这种情况的想法?

gdb

2
推荐指数
1
解决办法
1492
查看次数

标签 统计

c++ ×1

gcc ×1

gdb ×1

linux ×1

perf ×1