【问题标题】:c++ loop wrongly jumped out on centOS7?c++循环在centOS7上错误跳出?
【发布时间】:2018-04-19 04:56:47
【问题描述】:

我有一个项目编译后在ubuntu上运行良好,sn-p是这样的:

void Backtest::start() 
{

    std::cout << "start  !!" << std::endl;
    std::cout << bars.size()<< std::endl;

    int jj=0;
    while(jj<bars.size()){
        std::cout << "on bar " << jj<<std::endl;
        newBar(&bars[jj]);
        jj++;
    }
}

在 ubuntu 上一切正常,条形大小约为 3020,但在 centOS 7 上它仅在 jj =3 处终止,gdb 输出:

(gdb) next
start !!
3020
407     count = 0;
(gdb) 
408     jj=0;
(gdb) 
409     while(jj<bars.size()){
(gdb) 
410 std::cout << "on bar " << jj<<std::endl;
(gdb) 
on bar 0
411         newBar(&bars[jj]);
(gdb) 
412         jj++;
(gdb) 
409     while(jj<bars.size()){
(gdb) 
410 std::cout << "on bar " << jj<<std::endl;
(gdb) 
on bar 1
411         newBar(&bars[jj]);
(gdb) 
412         jj++;
(gdb) 
409     while(jj<bars.size()){
(gdb) 
410 std::cout << "on bar " << jj<<std::endl;
(gdb) 
on bar 2
411         newBar(&bars[jj]);
(gdb) 
412         jj++;
(gdb) 
409     while(jj<bars.size()){
(gdb) 
410 std::cout << "on bar " << jj<<std::endl;
(gdb) 
on bar 3
411         newBar(&bars[jj]);
(gdb) 
asd
|100000.000000,100000.000000|
get cash 100000.0
412         jj++;
(gdb) 
409     while(jj<bars.size()){
(gdb) 
415 }

在 gdb 409 它奇怪地给出了空循环并终止,这里可能有什么问题???

void Backtest::newBar(Bar* b)
{
    if(Number == count+1){
        tempbars.push_back(*b);
        crossLimitOrder();
        strategyPy->onBar(tempbars);
        tempbars.clear();
        count = 0;
    }else{
        tempbars.push_back(*b);
        count ++;
    }        
}

PS newBar 是项目中的其他东西,它基本上是调用一个 strategyPy 来做某事,这将调用一个 boost python 模块来调用 C++ 函数(它为 python 提供了一些 API,包括 getCash(),这就是它的原因在调试信息中打印出来)

【问题讨论】:

  • 什么是newBar()?此外,如果该函数是非静态成员,则 Backtest 实例最好是有效的。
  • 你有另一个线程在运行吗? “拿钱”从何而来?
  • 刚刚更新了新栏

标签: c++ loops centos gdb


【解决方案1】:

get cash 之后打印jj 的值会很有趣。

我的水晶球说它会有一个非常大的正值或负值,在这种情况下,您的问题是 newBar 中某处的堆栈缓冲区溢出,或者它调用的函数之一。

使用Address Sanitzer (g++ -fsanitize=address ...) 构建您的程序应该可以直接指出问题所在。

更新:

我在拿到现金后打印 jj 的值,但它说它仍然是 3

你必须意识到这一点

  • 没有魔法(jj 不是真正的 3,或者你的编译器坏了(不太可能))
  • 调试是一种技能

可能发生的情况是 GDB 只打印 jj 的低 32 位,但编译器使用整个 64 位寄存器(假设是 64 位机器)来执行比较(并期望高位都是0)。 newBar 中的某些内容将 jj 的高位设置为非零值。

现在,您可以通过以下几种方式之一对其进行调试:

  • 使用disas 命令,找到实际的cmp 指令,在比较时检查寄存器,或者
  • jj 的类型从int 更改为size_t(至少GDB 不会执行任何截断),或者
  • 在 Address Sanitizer 下运行(如前所述)。

【讨论】:

  • 我在拿到现金后打印 jj 的值,但它说它仍然是 3
猜你喜欢
  • 2018-09-06
  • 2021-08-31
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2018-09-23
  • 2014-12-11
相关资源
最近更新 更多