Есть программка, многопоточная. Выглядит приблизительно так:
LibraryInitialize();
for (int i = 1; i < 1000; ++i)
LibraryCall(arg1, arg2, arg3);
LibraryDeinitialize();
где Library — моя библиотечка, которая в LibraryInitialize() создаёт
несколько потоков, в LibraryCall() общается с ними, в
LibraryDeinitialize() соответственно всё подчищается.
После запуска её под rational quantify, получаем репорт, в котором
написано, что функция LibraryCall запускается всего N раз (N << 1000,
варьируется от запуска к запуску, от 10 до 500), функция
LibraryDeinitialize() не вызывается вообще. При этом quantify не ругается,
что программа сломалась, никаких сообщений об ошибках не выводится.
При этом во всех мыслимых и не очень способах запуска (под отладчиком, без
отладчика, в debug/release сборках, в rational purify, несколько других
приложений, которые эту библиотеку используют, тесты) всё проходит гладко,
нигде ничего не ломается, raional purify не ругается (при запуске в нём
приложение дорабатывает до конца, функция запускается все 1000 положенных
раз).
В чём может быть проблема? Не думаю, что в такой широко используемой(?)
тулзе. А что может быть не так в приложении, при условии, что больше
никаких симптомов нет, я тоже не могу себе представить. Может есть
какие-то идеи?
Приложение многопотоковое, как я уже сказал, общается с сетью. Какие ещё
моменты нужно уточнить не знаю, если надо могу рассказать подробнее.
Спасибо всем.
ps сейчас попробую ещё какой-нибудь профайлер, о результатах доложу
Posted via RSDN NNTP Server 2.0
Охохо... в общем, как обычно "оно само собой заработало".
Ну да в общем-то понятно — на улице потеплело, луна взошла...
Если есть какие-то соображения — высказывайтесь пожалуйста, а то я совсем
не знаю
Posted via RSDN NNTP Server 2.0
Здравствуйте, green.nsk, Вы писали:
GN>В чём может быть проблема? Не думаю, что в такой широко используемой(?) тулзе. А что может быть не так в приложении, при условии, что больше никаких симптомов нет, я тоже не могу себе представить. Может есть какие-то идеи?
Где-то в одном из LibraryCall происходит исключение либо случайный вызов завершения потока / процесса.
Раз программа многопоточная, то использование дебаггеров изменяет временную диаграмму. Поэтому с ними и без них эффекты разные.
Попробуй запустить под каким-нибудь средством контроля чистоты рук — Numega BoundsChecker или Rational Purify.
Даже если собственно вылета не произойдёт, он укажет на те места, где такой вылет потенциально возможен.
А ещё можно обернуть код в try-catch (а то и __try-__except) блоки и изловить собственно момент броска (разумеется, если твой код не вызывает нечаянно terminate()).
Кстати о terminate. Если произошло исключение и в ходе размотки стека, в деструкторе произошло ещё одно исключение — то это мгновенно приведёт именно к terminate(). Так что посмотри, нет ли у тебя throw.
... << RSDN@Home 1.2.0 alpha rev. 655>>
> Попробуй запустить под каким-нибудь средством контроля чистоты рук —
> Numega BoundsChecker или Rational Purify.
> Даже если собственно вылета не произойдёт, он укажет на те места, где
> такой вылет потенциально возможен.
При этом во всех мыслимых и не очень способах запуска (под отладчиком, без
отладчика, в debug/release сборках, в rational purify, несколько других
приложений, которые эту библиотеку используют, тесты) всё проходит гладко,
нигде ничего не ломается, rational purify не ругается (при запуске в нём
приложение дорабатывает до конца, функция запускается все 1000 положенных
раз).
purify показывает все исключения, которые возникают в процессе работы, все
они в общем-то нормальные и ожидаемые (возникают из-за того, что
программка тестовая).
> А ещё можно обернуть код в try-catch (а то и __try-__except) блоки и
> изловить собственно момент броска (разумеется, если твой код не вызывает
> нечаянно terminate()).
> Кстати о terminate. Если произошло исключение и в ходе размотки стека, в
> деструкторе произошло ещё одно исключение — то это мгновенно приведёт
> именно к terminate(). Так что посмотри, нет ли у тебя throw.
думаю, этот terminate все rational'овские тулзы отловили бы и мне
показали. да и деструкторы у меня не бросают исключений.
Насчёт того, что временные диаграммы под дебаггером и без разные я конечно
согласен, только как это искать при таких странных исходных данных я слабо
себе представляю (когда программа ломается только в rational quantify, да
и то как-то странно).
BoundsChecker попробую найти и погонять.
ps: я там уже писал, что всё заработало. И я в общем-то не представляю
себе, как можно повторить поломку, так что тема скорее всего закрыто и
придётся списать на "глюки винды".
Posted via RSDN NNTP Server 2.0
Здравствуйте, green.nsk, Вы писали:
GN>BoundsChecker попробую найти и погонять.
Я не пользовался Purify, — не знаю его способности к ловле тараканов. А вот BoundsChecker показывает такие вещи, как выход за границы массива или вызов APIшных функций с неверными параметрами. Правда, иногда на него нападает паранойя, но выявить проблемные места ещё до того, как они привели к феерверку — помогает неплохо.
GN>ps: я там уже писал, что всё заработало. И я в общем-то не представляю себе, как можно повторить поломку, так что тема скорее всего закрыто и придётся списать на "глюки винды".
Может быть, просто кривая сборка? Например, прекомпилированный заголовок был общим и для дебага, и для релиза, или какие-то старые .obj-файлы затесались.
Если вдруг воспроизведётся — то попробуй методом деления пополам.
int const okay = 500; // меняй её от 1 до 1000: 500, 250, 375 и т.д.
for(i=0; i!=okay; ++i) LibraryCall(arg1,arg2,arg3); // в этом отрезке всё работает
MessageBox("Checkpoint! Можно прицепить к процессу дебаггер");
for(i=okay; i!=N; ++i) LibraryCall(arg1,arg2,arg3); // где-то здесь валится... или не валится, из-за сдвига диаграммы
в конце концов выяснишь, на каком шаге он валится — и попробуй отлаживать прицельно с этого места. Или точно так же, натыкать контрольных точек уже внутри LibraryCall.
... << RSDN@Home 1.2.0 alpha rev. 655>>