将程序从linux移植到solaris,使用solarisstudio 12.3构建它。
它有以下定义:
typedef std::list<ISocketMultiplexerJob *> CSocketJobs;
typedef CSocketJobs::iterator CJobCursor;
CSocketJobs m_socketJobs;
和这段代码:
CSocketMultiplexer::CJobCursor
CSocketMultiplexer::nextCursor(CJobCursor cursor)
{
CLock lock(m_mutex);
CJobCursor j = m_socketJobs.end();
CJobCursor i = cursor;
while (++i != m_socketJobs.end()) {
if (*i != m_cursorMark) { // CRASHES HERE!!
j = i;
// move our cursor just past the job
m_socketJobs.splice(++i, m_socketJobs, cursor);
break;
}
}
return j;
}
它在上面指定的行崩溃,因为:
(dbx) print i
i = {
_C_node = (nil)
}
看起来像“++ i”迭代从列表中删除但是测试反对 m_socketJobs.end()无法看到它并让它通过。需要帮助调试,例如,我如何以更加c ++的方式分析dbx中的* i?
nextCursor()的来电者在此代码段中,&lt;&gt;:
// collect poll entries
if (m_update) {
m_update = false;
pfds.clear();
pfds.reserve(m_socketJobMap.size());
CJobCursor cursor = newCursor();
CJobCursor jobCursor = nextCursor(cursor);
while (jobCursor != m_socketJobs.end()) {
ISocketMultiplexerJob* job = *jobCursor;
if (job != NULL) {
pfd.m_socket = job->getSocket();
pfd.m_events = 0;
if (job->isReadable()) {
pfd.m_events |= IArchNetwork::kPOLLIN;
}
if (job->isWritable()) {
pfd.m_events |= IArchNetwork::kPOLLOUT;
}
pfds.push_back(pfd);
}
jobCursor = nextCursor(cursor); //FATAL CALL
}
这是函数newCursor():
CSocketMultiplexer::CJobCursor
CSocketMultiplexer::newCursor() {
CLock lock(m_mutex);
return m_socketJobs.insert(m_socketJobs.begin(), m_cursorMark);
}
我做了一些修改,发现newCursor()/ nextCursor()sorta工作并且不起作用....也许另一个线程正在伤害上下文。在下面的例子中(嵌入在我的程序中)第一个init“CJobCursor c = newCursor();”是健壮的,我可以插入行“c = nextCursor(c);”在我的程序中的任何地方,它不会崩溃。但下一个 评论“坏”是有缺陷的,并在第二次nexCursor()调用时崩溃。 我发现这很有趣,但还没有解释。我想我需要继续测试 整个程序内部,因为上下文是杀死事物。你觉得怎么样?
void
CSocketMultiplexer::serviceThread(void*)
{
std::vector<IArchNetwork::CPollEntry> pfds;
IArchNetwork::CPollEntry pfd;
CJobCursor c = newCursor();
CJobCursor j = nextCursor(c);
c = nextCursor(c);
c = nextCursor(c);
// service the connections
for (;;) {
CThread::testCancel();
// wait until there are jobs to handle
{
CLock lock(m_mutex);
while (!(bool)*m_jobsReady) {
m_jobsReady->wait();
}
}
// lock the job list
lockJobListLock();
lockJobList();
// collect poll entries
if (m_update) {
m_update = false;
pfds.clear();
pfds.reserve(m_socketJobMap.size());
CJobCursor cursor = newCursor(); //BAD, Ill-fated object
CJobCursor jobCursor = nextCursor(cursor);
c = nextCursor(c);
cursor = nextCursor(cursor); // SEGV's here
while (jobCursor != m_socketJobs.end()) {
ISocketMultiplexerJob* job = *jobCursor;
if (job != NULL) {
pfd.m_socket = job->getSocket();
pfd.m_events = 0;
if (job->isReadable()) {
pfd.m_events |= IArchNetwork::kPOLLIN;
}
if (job->isWritable()) {
pfd.m_events |= IArchNetwork::kPOLLOUT;
}
pfds.push_back(pfd);
}
c = nextCursor(c);
jobCursor = nextCursor(cursor);
}
c = nextCursor(c);
deleteCursor(cursor);
}
答案 0 :(得分:1)
看起来“++ i”迭代从列表中删除了
不,我认为它看起来像一个无效的迭代器(可能是默认构造的),而不是一个过去的迭代器。
std::list<T>::iterator
需要能够再次向下递减列表,因此它不能指向null,否则一旦你到达终点并且它变为null,你就不能再向后。通常,过去的std::list
迭代器必须指向一个标记节点。
因此,i
未指向m_socketJobs
的任何元素,这意味着m_socketJobs.end()
无法从i
到达,无论您增加多少次i != m_socketJobs.end()
,所以assert( i != CJobCursor() )
{1}} 始终将成为现实。
尝试将(++i != m_socketJobs.end())
添加到函数的顶部,我打赌它会在那里中止,因为我认为你用无效的迭代器调用了函数。
你不应该只是因为{{1}}为真,迭代器是可解除引用的。