c ++循环错误地跳出了centOS7?

时间:2017-11-06 22:31:03

标签: c++ loops centos gdb

我有一个在编译后在ubuntu上运行良好的项目,该代码片段如下:

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(),这就是为什么它打印出调试信息)

1 个答案:

答案 0 :(得分:1)

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

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

使用Address Sanitzerg++ -fsanitize=address ...)制作您的计划应该直接指出问题。

<强>更新

  

我在获得现金之后打印jj的价值,但它仍然表示仍然是3

你必须意识到这一点

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

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

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

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