我在两台机器上本地编译了完全相同的源代码/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
没有“看到”相同的构造函数集,以及为什么代码似乎没有被调用那么多——尽管为什么它与“全部或全部”不同是一个谜。