我在两台机器上本机编译完全相同的源代码/ 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
没有“看到”同一组构造函数,以及为什么代码似乎没有被调用那么多 - 尽管为什么它会与“一切或什么都没有”不同是一个谜。
答案 0 :(得分:2)
您正在比较不同版本的gdb以及不同版本的gcc。那个变数太多了。
很可能是debuginfo差异。但仅仅通过这些信息就无法说出来。
要知道的是,C ++ ABI指定要发出的多个构造函数副本。有“主管”和非主管变种。 gdb会在它找到的所有部分上放置断点。
但是,我认为这可能会受到debuginfo和其他因素的影响。从源到可执行文件发生的事情并不总是很明显......如果你真的想找到发生这种情况的原因,你可以使用像“nm”和“readelf -wi”这样的工具来挖掘符号和debuginfo。