dbx — c ++ стандартное использование списка библиотек?

Портирование программы из 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 () не смог его увидеть и пропустил. Нужна помощь в отладке, например, как я могу проанализировать * i в dbx в более с ++ восприимчивой манере?

Вызывающая функция nextCursor () находится в этом фрагменте, <>:

                // 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 () работает и не работает …. возможно, другой поток наносит вред контексту. В приведенном ниже примере (встроен в мою программу) первый инициализация «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);
}

2

Решение

Похоже, итерация «++ i» исчезла из списка

Нет, я думаю, что это выглядит как недопустимый итератор (может быть, построенный по умолчанию), а не зацикленный итератор.

std::list<T>::iterator Нужно иметь возможность снова уменьшаться в обратном направлении по списку, поэтому он не может указывать на ноль, иначе, как только вы достигли конца, и он стал нулевым, вы не сможете вернуться назад снова. Обычно это конец std::list итератор должен указывать на сторожевой узел.

Так что ваши i не указывает ни на один элемент m_socketJobs Который означает, что m_socketJobs.end() недоступен из i независимо от того, сколько раз вы увеличиваете его, так i != m_socketJobs.end() является всегда собирается быть правдой.

Попробуйте добавить assert( i != CJobCursor() ) к вершине функции, и я держу пари, что она там прерывается, потому что я думаю, что вы вызвали функцию с недопустимым итератором.

Вы не должны предполагать, что только потому, что (++i != m_socketJobs.end()) верно, итератор разыменовывается.

1

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector