Моя программа падает в boost :: thread :: thread_start_function, как я могу отладить - PullRequest
0 голосов
/ 22 февраля 2011

Я собрал программу на C ++ с использованием Visual Studio 2008. Релиз и отладочная версия аварийно завершаются.Частота сбоев зависит от компьютера, на котором он работает (от одного раза в неделю до каждого часа).

Программа использует boost asio для связи по TCP, а также wxWidget для пользовательского интерфейса.Тем не менее, сбои не связаны с какой-либо проблемой TCP или взаимодействием с пользовательским интерфейсом, так как в основном это происходит, когда программа простаивает.

Вот стек вызовов, который у меня возникает при сбое:

msvcr90d.dll!_NMSG_WRITE(int rterrnum=10)  Line 198 C
msvcr90d.dll!abort()  Line 59 + 0x7 bytes   C
msvcr90d.dll!terminate()  Line 130  C++
enf_client.exe!boost::thread::thread_start_function(void * param=0x00161e60)  Line 184  C++
msvcr90d.dll!_callthreadstartex()  Line 348 + 0xf bytes C
msvcr90d.dll!_threadstartex(void * ptd=0x01385d28)  Line 331    C
kernel32.dll!7c80b729()     
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll

IЯ не знаю, как отладить эту вещь.Если у вас есть представление о том, где искать, это было бы замечательно.

EDIT

Я заметил это в моей трассировке отладки, непосредственно перед сбоем:

First-chance exception at 0x7c812afb in enf_client.exe: Microsoft C++ exception: std::out_of_range at memory location 0x0189efd4..

Я не могу понять, что находится в памяти по этому адресу (выглядит много мусора):

L.H............. ð..0.=..zH. ð...ð.......

Какие функции могут вызвать это, кроме функции at контейнеров stl?

Ответы [ 4 ]

2 голосов
/ 22 февраля 2011

Вы пытались настроить отладчик так, чтобы он прерывался при возникновении исключения?(Меню отладки -> Исключения -> Исключения C ++ -> Установите флажок для std :: exception.)

2 голосов
/ 22 февраля 2011

Тот факт, что terminate () находится в вашем стеке вызовов, заставляет меня поверить, что вызывается чисто виртуальная функция.Относительно легко спровоцировать это с помощью следующего сценария:

  • Базовый класс, представляющий поток, запускает поток в ctor.Функция «execute» является чисто виртуальной
  • Подклассом, реализующим функцию «execute».

Время от времени поток, запущенный из Base ctor, начнет работать до База ctor полностью сделана.Следовательно, объект execute вызывается не полностью сконструирован, и вызывается метод execute Base, в результате чего происходит terminate ()

Такое «теперь и потом прекращение» () может быть вызвано несколькими другими сценариями.предложите вам поэкспериментировать с провоцированием, когда вы спите сразу после вызова, который фактически создает ваш поток.

1 голос
/ 22 февраля 2011

Не видя никакого кода, вам будет сложно сказать, в чем проблема.

Я бы сделал следующее:

Кажется, что terminate () вызывается внутри boost :: thread :: thread_start_function в блоке catch. В Windows я бы вызвал DebugBreak () перед std :: terminate () и запустил приложение (конечно, вы должны запустить отладочную версию). Когда ошибка повторяется, DebugBreak запустит ваш отладчик и будет ждать в этот момент. Оттуда вы можете проанализировать трассировку стека и проверить, кто запустил этот поток, и проверить, что происходит внутри.

0 голосов
/ 01 марта 2011

Учитывая, что у меня есть std::out_of_range, я посмотрел все свои вызовы функции at.

И вот оно было:

std::string temp; ... ; if (temp.size() >= 8) temp.at(8) = '0'

Что должно было быть: if (temp.size() >= 9) temp.at(8) = '0'

Я все еще не понимаю, почему у меня не было больше отладочной информации об этом исключении в режиме отладки. Это может быть связано с тем, что он был в потоке пользовательского интерфейса, которым управляет wxWidget.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...