设置gdb断点选择另一组构造函数32位对64位

时间:2013-04-01 04:26:21

标签: linux gdb 32bit-64bit breakpoints

我在两台机器上本机编译完全相同的源代码/ make文件:Linux Fedora 16 32位和Linux Fedora 17 64位。

在32位机器上:

(gdb) break FRS::FRS
Breakpoint 4 at 0x804ea29: file ntfs.cpp, line 751.
Breakpoint 5 at 0x804e18f: file ntfs.cpp, line 505.
warning: Multiple breakpoints were set.
Use the "delete" command to delete unwanted breakpoints.

GNU gdb (GDB) Fedora (7.3.50.20110722-16.fc16)

在64位机器上:

(gdb) break FRS::FRS
Breakpoint 1 at 0x407daf: file ntfs.cpp, line 751.

GNU gdb (GDB) Fedora (7.4.50.20120120-54.fc17)

使用32位调试会话的知识,我设置了另一个断点(并删除了第一个断点)来调试正确的函数。但是,它以不同的方式执行,并且只针对同一测试用例点击该构造函数两次。在32位环境中,它会破坏断点十几次。

FRS::FRS (MFT *Mft, uint32 MFTRef, bool shallow)   // this is line 505
{
        memset (this, 0, sizeof *this);
        ParentMFT = Mft;
        MFTReference = MFTRef;
        Volume  *vol = GetParentVolume ();

        frs_bytes = ParentMFT -> GetFRSSizeInBytes();
        frs_buf = new uint8 [frs_bytes];
        if (!frs_buf)
        {
                fprintf (stderr, "FRS: alloc(%u) err\n", frs_bytes);
                exit (1);
        }

        int     sects = ParentMFT->GetFRSSizeInSectors();       // sectors per FRS
        bool    rc;

        if (!MFTRef)
                rc = vol -> RelativeRead (frs_buf, ParentMFT->GetMFTStart(), sects);
        else
        {
                uint32 FirstLsn = Mft -> LogicalFromVirtual(MFTReference * sects);
                uint32 LastLsn  = Mft -> LogicalFromVirtual(MFTReference * sects + sects - 1);

                if (FirstLsn + sects - 1 == LastLsn)    // is contiguous?
                        rc = vol -> RelativeRead (frs_buf, FirstLsn, sects);    // optimize read
                else
                {       // not contiguous:  read sectors one at a time
                        for (int j = 0;  j < sects;  ++j)
                        {
          ... (170 more lines)


// copy constructor
FRS::FRS(FRS *frs)   // this is line 751
{
        int     j;
        *this = *frs;
        if (frs_buf)
        {
                frs_buf = new uint8 [frs_bytes];
                memcpy (frs_buf, frs -> frs_buf, frs_bytes);
        }

        DAttr = NULL;
        StreamList = NULL;
      ...  // 50 more lines

64位代码有什么本质上不同的东西可以编译掉这个函数吗? (它是一个204行函数,所以我在证明它是非平凡的之后将其截断了。)

什么可以解释为什么gdb没有“看到”同一组构造函数,以及为什么代码似乎没有被调用那么多 - 尽管为什么它会与“一切或什么都没有”不同是一个谜。

1 个答案:

答案 0 :(得分:2)

您正在比较不同版本的gdb以及不同版本的gcc。那个变数太多了。

很可能是debuginfo差异。但仅仅通过这些信息就无法说出来。

要知道的是,C ++ ABI指定要发出的多个构造函数副本。有“主管”和非主管变种。 gdb会在它找到的所有部分上放置断点。

但是,我认为这可能会受到debuginfo和其他因素的影响。从源到可执行文件发生的事情并不总是很明显......如果你真的想找到发生这种情况的原因,你可以使用像“nm”和“readelf -wi”这样的工具来挖掘符号和debuginfo。