У меня есть небольшое однопоточное приложение C ++, скомпилированное и связанное с использованием Visual Studio 2005, которое использует ускорение (crc, program_options и tokenizer), немного STL и различные другие системные заголовки.
(Его основная цель - прочитать файл .csv и создать собственный двоичный файл .dat и парный .h, объявляющий структуры, которые «объясняют» формат .dat.)
Инструмент дает сбой (нарушение прав доступа на NULL) при запуске вне отладчика, только в выпуске. Например. нажатие F5 не приводит к сбою инструмента, в отличие от Ctrl-F5. Когда я снова подключаю отладчик, я получаю такой стек:
ntdll.dll!_RtlAllocateHeap@12() + 0x26916 bytes
csv2bin.exe!malloc(unsigned int size=0x00000014) Line 163 + 0x63 bytes C
csv2bin.exe!operator new(unsigned int size=0x00000014) Line 59 + 0x8 bytes C++
>csv2bin.exe!Record::addField(const char * string=0x0034aac8) Line 62 + 0x7 bytes C++
csv2bin.exe!main(int argc=0x00000007, char * * argv=0x00343998) Line 253 C++
csv2bin.exe!__tmainCRTStartup() Line 327 + 0x12 bytes C
Строка, в которой происходит сбой, выглядит довольно безобидно:
pField = new NumberField(this, static_cast<NumberFieldInfo*>(pFieldInfo));
... Я не верю, что он дошел до конструктора, он просто выделяет память перед переходом к конструктору. Он также выполнил этот код десятки раз к моменту сбоя, обычно в согласованном (но в остальном не подозрительном) месте.
Проблема исчезает при компиляции с / MTd или / MDd (время выполнения отладки) и возвращается при использовании / MT или / MD.
NULL загружается из стека, и я могу видеть его в памяти. _RtlAllocateHeap @ 12 + 0x26916 байт кажется огромным смещением, как будто был сделан неправильный переход.
Я пробовал _HAS_ITERATOR_DEBUGGING в отладочной сборке, и это не вызвало ничего подозрительного.
Удаление HeapValidate в начале и в конце Record :: addField показывает «кучу ОК» вплоть до момента ее сбоя.
Раньше это работало - я не совсем уверен, что изменилось с этого момента до последней компиляции инструмента (возможно, много лет назад, возможно, в более старой версии VS). Мы пробовали более старую версию boost (1.36 против 1.38).
Прежде чем вернуться к исследованию кода вручную или передать его в PC-Lint и просмотреть его вывод, есть ли предложения о том, как это эффективно отлаживать?
[Я буду рад дополнить вопрос дополнительной информацией, если вы запросите информацию в комментариях.]