Debug 经验积累 续

16 views
Skip to first unread message

LeoReis

unread,
May 24, 2007, 5:56:13 AM5/24/07
to Wisdom and beauty form a very rare combination.
之前碰到一个诡异问题,程序读取文件有时成功有时不成功,匪夷所思。当时没有搞定,今天再次碰到这个问题,我怒!于是下定决心揪出它拍死。
因为读文件的引擎是跨平台的(ps2,psp,pc等),搞得十分的复杂难读,上次就是为此放弃追查的,因为不发了就放过了。罪过罪过。问题没有解决而
只是掩盖过去,它迟早会在更难受的时刻给你带来更大的麻烦。
废话不说了。直接跑编译好的程序,每次都报文件找不到,而文件明明就在那里。首先排除了文件路径的问题。用gdb跟踪调试,问题居然不出来了,日。
再试,还不出。再试,出来了。慢慢发现规律,用gdb run 3次基本上就能出来,并且出来之后会反复再出。于是反复run直到问题出现之后再重新
run,在出问题的前一个函数设置断点然后step进去一句句看,终于被我看到一个该死的代码错误。列出如下:
int32 fsFileOpsPC::Open(fsDevice device, const char* filename, uint32
mode)
{
。。。。。。
FILE* fp = fopen(filename, modestring);

if (fp == 0)
{
return -1;
}

return (int)fp;
}


bool8 fsFileMgr::Open_normal(fsDevice device, const char * filename,
int32 openmode, fsHandle* file)
{
int32 filehandle = m_file_op->GetIt()->Open(device, filename,
openmode);

if (filehandle < 0)
{
file->m_last_error = m_file_op->GetIt()->GetLastError();
return false;
}
。。。。。。
}

前一个函数被后一个函数调用,返回值作了小于0的检查。
而这个该死的返回值是一个指针!!

------------------------------------------------------------------------------------------
指针作为整数来用不是不可以,但是要十分谨慎。
判断尽量用强条件(比如==)而不要用弱条件(< 0)
函数返回值意义要明确。

LeoReis

unread,
Jun 13, 2007, 12:05:03 AM6/13/07
to Wisdom and beauty form a very rare combination.
昨天碰到一个当机,当在 stl 的 map 的 iterator 的++ 里面。
同事很是不解,怀疑是内存被破坏了。
我看了一下,原来问题出在map的遍历中使用了erase,这个问题很久以前碰到过。
在map的遍历过程中,erase一个iterator,然后让它++这自然是有问题的,它都被erase了还怎么++
示例如下
for( std::map<int,int>::iterator it = mapIntInt.begin(); it !=
mapIntInt.end(); it++ )
{
if( it->second == 100 )
mapIntInt.erase(it);
}

vc的stl实现中返回的删除后的下一个iterator,但它同时指出这不是遵从c++标准的。
c++标准是不返回值的。
如果要在循环遍历的时候删除某个iterator,可以把这个iterator的first记录下来,等循环遍历完成之后再以key的方式删除之。
例如:
std::list< int > list_Need_erase;
for( std::map<int,int>::iterator it = mapIntInt.begin(); it !=
mapIntInt.end(); it++ )
{
if( it->second == 100 )
list_Need_erase.push_back(it->first);
}
while( list_Need_erase.size() > 0 )
{
mapIntInt.erase( list_Need_erase.front() );
list_Need_erase.pop_front();
}

另外需要指出的一点是如果经常需要用到insert和erase,那么是否采用map作为数据结构就值得仔细考虑了。
因为map的优势在于查找和定位效率高,而缺点就是插入和删除效率低。

LeoReis

unread,
Jun 21, 2007, 5:07:40 AM6/21/07
to Wisdom and beauty form a very rare combination.
1>xxxxx fatal error C1001: 编译器中发生内部错误。
1>(编译器文件"F:\SP\vctools\compiler\utc\src\P2\ehexcept.c",第 971 行)
1> 要解决此问题,请尝试简化或更改上面所列位置附近的程序。
1>请选择 Visual C++
1>"帮助"菜单上的"技术支持"命令,或打开技术支持帮助文件来获得详细信息。
1>LINK : fatal error LNK1257: 代码生成失败

今天碰到如上的问题,经仔细查验发现原来是二维数组的初始值给的不对。如下:
CString arr[][2] =
{
"abcd", "efgh",
"eoa"
};

补齐即可。
CString arr[][2] =
{
"abcd", "efgh",
"eoa","eoa"
};

LeoReis

unread,
Jul 3, 2007, 5:52:22 AM7/3/07
to Wisdom and beauty form a very rare combination.
今天在此碰到一个妖问题:在linux下编译一个项目时出现大量的如下错误
undefined reference to `xxxx
而这些函数明明确确在一个库中存在,并且也连接了该库。
后通过尝试发现在link的后面再加一次 -lmyLib 就通过了。(myLib为示例名字,就是前面说的存在该函数的库)
原来link后面的参数顺序也是有关系的,有点想不明白。
不懂。
Reply all
Reply to author
Forward
0 new messages