2013-04-25 70 views
0

我有一个程序,它在一个特定的线段错误:段错误发生时,GDB打破上线,但段错误后运行线示出没有违反

uint64_t中smaller_num = *(uint64_t中*)(smaller_base +指数);

GDB成功捕获段错误,允许我调试问题。但是,如果我请从GDB提示行,没有内存访问冲突发生:

(GDB)p smaller_num = *(uint64_t中*)(smaller_base +指数)

任何人都可以提供关于如何一些建议,调试这个问题?由于我确认了位于small_base + index处的内存存在,因此我失去了文字和想法。它可以是铸造的东西吗?

在此先感谢。

编辑:提供更多的代码,但它确实很简单。我大量编辑了代码以显示索引的重点。

uint64_t ** find_difference(unsigned char * larger_base, 
           uint64_t size, 
           unsigned char * smaller_base, 
           uint64_t tmap_size) 
{ 
    uint64_t len = size < tmap_size?size:tmap_size; 
    uint64_t index=0; 
    while(index<len) 
    { 
      uint64_t larger_num = *(uint64_t*)(larger_base+index); 
      uint64_t smaller_num = *(uint64_t*)(smaller_base+index); 
      if(larger_num > smaller_num) 
      { 
       ... do stuff 
      } 
      index++; 
    } 

    ... 
} 

编辑#2:现在我正在考虑这个问题,指针解引用超出len是否可行?这是我的理解,x86号码存储从高地址到低地址。因此,在内存中,数字0x01020304被存储为0x04 0x03 0x02 0x01。它是否正确?如果这不是真的,那么尊重将超出缓冲区的末端。但是,在GDB中,我验证了地址是可访问的。

+0

上下文中的一些代码可以帮助我们。 – akluth 2013-04-25 14:47:45

+0

请详细说明small_base和索引类型。 – Nikolai 2013-04-25 14:49:31

回答

1

我不知道你如何使用find_difference()函数和传递给函数的参数值,但我怀疑你的指针算术是错误的。

您正在将large_base和smaller_base递增1并将结果地址转换为u64 *。 如果大小是以字节为单位,那么你应该检查large_base + index + 8的大小。

+0

大小是以字节为单位的缓冲区的大小。我认为您的评论与我的第二次修改的问题类似,并且是正确的。索引将使用超过缓冲区末尾8个字节的index = size-1。我会核实并回复。 Bah,它非常简单,谢谢你的额外眼睛。 – user2320249 2013-04-25 19:31:21

+0

证实我的指针数学被搞砸了会检查右手边界。 – user2320249 2013-04-25 19:57:37

0

你原来的指针运算添加指数(无符号字符*)它是一个地址铸造uint64_t中导致未对齐的内存负载,即试图取消引用一个(uint64_t中*)前不是8的倍数。这可以在调试器中工作,但会在程序中产生SEGFAULT。