Программа вылетает только при сборке релиза - как отлаживать?

У меня здесь проблема типа «Кот Шредингера» - моя программа (на самом деле набор тестов для моей программы, но, тем не менее, программа) дает сбой, но только при ее создании в режиме выпуска и только при запуске из командной строки. . Посредством отладки пещерного человека (т.е. повсюду неприятных сообщений printf ()) я определил метод тестирования, при котором происходит сбой кода, хотя, к сожалению, фактический сбой, похоже, происходит в каком-то деструкторе, поскольку последние сообщения трассировки, которые я вижу, находятся в другие деструкторы, которые выполняются чисто.

Когда я пытаюсь запустить эту программу внутри Visual Studio, она не дает сбоев. То же самое и при запуске из WinDbg.exe. Сбой происходит только при запуске из командной строки. Кстати, это происходит под Windows Vista, и, к сожалению, у меня сейчас нет доступа к машине XP для тестирования.

Было бы очень хорошо, если бы я мог заставить Windows распечатать трассировку стека или что-нибудь, кроме простого завершения программы, как если бы она вышла без ошибок. Есть ли у кого-нибудь совет относительно того, как я могу получить здесь более значимую информацию и, надеюсь, исправить эту ошибку?

Обновлено: проблема действительно была вызвана массивом вне пределов, что я описываю больше в этом посте. Спасибо всем за помощь в поиске этой проблемы!

Можете ли вы привести образец этого метода тестирования?

akalenuk 09.10.2008 12:31

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

Nik Reiman 09.10.2008 14:24

Большинство ответов - не более чем предположения. Существует несколько распространенных методов анализа сбойных сборок выпуска без подключения отладчика: stackoverflow.com/a/18513077/214777?stw=2

Sebastian 29.08.2013 18:04

Может это не твоя вина: Опасен ли уровень оптимизации -O3 в g ++?

Brent Bradburn 15.04.2017 21:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
98
4
76 612
28
Перейти к ответу Данный вопрос помечен как решенный

Ответы 28

Когда я раньше сталкивался с подобными проблемами, это обычно происходило из-за инициализации переменной. В режиме отладки переменные и указатели автоматически инициализируются нулем, а в режиме выпуска - нет. Поэтому, если у вас есть такой код

int* p;
....
if (p == 0) { // do stuff }

В режиме отладки код в if не выполняется, но в режиме выпуска p содержит неопределенное значение, которое вряд ли будет 0, поэтому код выполняется, часто вызывая сбой.

Я бы проверил ваш код на наличие неинициализированных переменных. Это также может относиться к содержимому массивов.

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

steffenj 09.10.2008 11:56

В режиме отладки переменные обычно инициализируются некоторой «константой, определенной компилятором», которую можно использовать при отладке, чтобы указать, в каком состоянии находится переменная. Например: указатели NULL или 0xDeadBeef популярны.

Martin York 09.10.2008 19:38

Среда выполнения отладки обычно инициализирует память некоторым ненулевым значением, в частности, чтобы тесты указателя NULL заставляли код действовать так, как если бы указатель был ненулевым. В противном случае у вас есть код, который правильно работает в режиме отладки, который вызывает сбой в режиме выпуска.

Michael Burr 09.10.2008 21:23

Нет, переменные вообще не инициализируются, и все равно UB «использовать» их, пока они не назначены. Однако базовое содержимое памяти часто предварительно заполняется 0x0000000 или 0xDEADBEEF или другими распознаваемыми шаблонами.

Lightness Races in Orbit 05.04.2011 15:45

Что-то подобное случилось со мной однажды с GCC. Оказалось, что это слишком агрессивная оптимизация, которая включалась только при создании финального релиза, а не в процессе разработки.

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

Мне потребовалось много времени, чтобы отследить это, и я пришел к нему только потому, что спросил в группе новостей, и кто-то заставил меня подумать об этом. Итак, позвольте мне ответить вам одолжением на случай, если это произойдет и с вами.

Подобные сбои почти всегда возникают из-за того, что среда IDE обычно устанавливает для содержимого неинициализированной переменной нули, null или какое-либо другое такое «разумное» значение, тогда как при исходном запуске вы получите любой случайный мусор, который система подберет.

Поэтому ваша ошибка почти наверняка заключается в том, что вы используете что-то вроде использования указателя до того, как он был должным образом инициализирован, и вам сходит с рук в среде IDE, потому что он не указывает на что-либо опасное - или значение обрабатывается вашим проверка ошибок - но в режиме выпуска делает что-то неприятное.

Вы можете установить WinDbg в качестве посмертного отладчика. Это запустит отладчик и подключит его к процессу, когда произойдет сбой. Чтобы установить WinDbg для посмертной отладки, используйте параметр / I (обратите внимание, что это заглавные):

windbg /I

Подробнее здесь.

Что касается причины, это, скорее всего, унифицированная переменная, как предполагают другие ответы.

И не забывайте, что вы можете заставить компилятор генерировать файлы PDB даже для сборок выпуска, хотя это не по умолчанию.

Michael Burr 09.10.2008 18:46

Единственный реальный ответ на вопрос действительно.

Sebastian 29.08.2013 16:43

Я нашел этот эта статья полезным для вашего сценария. Параметры компилятора ISTR немного устарели. Изучите параметры проекта Visual Studio, чтобы узнать, как создавать файлы pdb для сборки выпуска и т. д.

Что касается ваших проблем с получением диагностической информации, пробовали ли вы использовать adplus.vbs в качестве альтернативы WinDbg.exe? Чтобы присоединиться к запущенному процессу, используйте

adplus.vbs -crash -p <process_id>

Или запустить приложение в случае, если сбой произойдет быстро:

adplus.vbs -crash -sc your_app.exe

Полную информацию о adplus.vbs можно найти по адресу: http://support.microsoft.com/kb/286350

Чтобы иметь аварийный дамп, который можно проанализировать:

  1. Создайте файлы pdb для своего кода.
  2. Вы выполняете переустановку, чтобы ваши exe и dll загружались по одному и тому же адресу.
  3. Включить посмертный отладчик, такой как Доктор Ватсон
  4. Проверьте адрес аварийных отказов с помощью такого инструмента, как поиск аварий.

Вы также должны проверить инструменты в Инструменты отладки для windows. Вы можете отслеживать приложение и видеть все исключения первого шанса, которые были до исключения второго шанса.

Надеюсь, это поможет...

Ответ принят как подходящий

В 100% случаев, которые я видел или слышал, когда программа на C или C++ нормально работает в отладчике, но не работает при запуске извне, причина заключалась в записи за концом локального массива функции. (Отладчик помещает больше в стек, поэтому вероятность перезаписи чего-то важного снижается.)

Кто-нибудь, дайте этому человеку сигару! В моем случае я передавал StringBuilder, у которого не было достаточно большой емкости, для функции P / Invoke. Я думаю, это похоже на то, как кто-то пишет на вашем лице волшебным маркером, когда вы спите: под отладчиком они заканчивают каракули у вас на лбу, так что вы не замечаете, но без отладчика они в конечном итоге протыкают вас ножом в глаз ... что-то в этом роде. Спасибо за этот совет!

Nicholas Piasecki 20.08.2009 17:58

В моем случае это оказалось проблемой выравнивания на процессоре ARM, использующем Obj-C.

Almo 16.05.2013 16:16

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

Mooing Duck 29.08.2013 21:57

Еще 1 из 1 от меня, чтобы добавить к этому, что это ошибка.

Wuschelbeutel Kartoffelhuhn 07.10.2017 11:56

11 лет спустя, и это все еще звучит правдоподобно ... не забудьте зарезервировать свои векторы.

dav 19.05.2019 07:47

Хорошо, тогда как изменить поведение режима отладки, чтобы можно было отлаживать.

Paul Childs 17.07.2019 02:45

@PaulChilds Вы не можете изменить поведение --- Это необходимо отладчику для отладки. Но теперь, зная, где искать, вы сможете найти и исправить проблему без отладчика.

James Curran 18.07.2019 22:57

«Теперь знаю, где искать», но как все, что работает при отладке, говорит вам где, что проблема в том. Хотя я думаю, что в большинстве случаев ваш ответ верен, и знание того, что искать, - хорошее начало, просмотр большой базы кода для точного определения того, где именно находится проблема, может оказаться непомерно дорогостоящим.

Paul Childs 20.07.2019 03:12

В моем случае это оказалось вызвано to_string(a/b), где b - целое число, равное 0. Он никогда не будет segfault для режима отладки, но для режима выпуска этот код иногда работал, а иногда и терпел неудачу (в зависимости от того, где в программе он был ). Деление на целое число со значением 0 является неопределенным поведением, поэтому я думаю, поэтому оно работает в режиме отладки, но иногда не в режиме выпуска.

MindSeeker 12.08.2020 22:00

Подозрительно, что это могло произойти вне отладчика, а не внутри; запуск в отладчике обычно не меняет поведения приложения. Я бы проверил различия среды между консолью и IDE. Также, очевидно, скомпилируйте выпуск без оптимизаций и с отладочной информацией и посмотрите, повлияет ли это на поведение. Наконец, ознакомьтесь с инструментами посмертной отладки, которые предложили здесь другие люди, обычно вы можете получить от них какую-то подсказку.

Несмотря на то, что вы создали исполняемый файл в качестве релизного, вы все равно можете создавать файлы PDB (база данных программ), которые позволят вам выполнять трассировку стека и выполнять ограниченное количество проверок переменных. В настройках сборки есть возможность создавать файлы PDB. Включите это и повторно установите связь. Затем попробуйте сначала запустить из IDE, чтобы увидеть, не произойдет ли сбой. Если так, тогда отлично - вы готовы смотреть на вещи. Если нет, то при запуске из командной строки вы можете сделать одно из двух:

  1. Запустите EXE и перед сбоем выполните команду «Присоединить к процессу» (меню «Инструменты» в Visual Studio).
  2. После сбоя выберите вариант запуска отладчика.

Когда вас попросят указать на файлы PDB, просмотрите их, чтобы найти. Если PDB были помещены в ту же выходную папку, что и ваши EXE или DLL, они, вероятно, будут загружены автоматически.

PDB предоставляет ссылку на источник с достаточной символьной информацией, чтобы можно было видеть трассировки стека, переменные и т. д. Вы можете проверять значения как обычно, но имейте в виду, что вы можете получить ложные показания, поскольку проход оптимизации может означать только вещи появляются в регистрах, или события происходят в другом порядке, чем вы ожидаете.

NB: здесь я подразумеваю среду Windows / Visual Studio.

Я согласен с Рольфом. Поскольку воспроизводимость очень важна, у вас не должно быть режима без отладки. Все ваши сборки должны быть отлаживаемыми. Наличие двух целей для отладки более чем вдвое увеличивает отладочную нагрузку. Просто отправьте версию в «режиме отладки», если она не пригодна для использования. В таком случае сделайте его пригодным для использования.

Это может работать для 10% приложений, но, конечно, не для всех. Хотели бы вы играть в игры, выпущенные как сборки DEBUG? Отдать свой секретный код безопасности, защищенный торговой маркой, в режиме, удобном для разборки, может быть, даже вместе с PDB? Думаю, нет.

steffenj 09.10.2008 12:01

Штеффень: Я хочу, чтобы разработчики игр находили ошибки. В идеале, до их отправки, но если это будет после, я хочу, чтобы они могли получить достаточно информации, чтобы воспроизвести и отследить ее. если это секретный код, товарный знак не применяется. PDB? Банк данных белков? отладчик python?

wnoise 10.10.2008 02:36

ИМХО, это плохая идея. Исполняемые файлы больше, они не оптимизированы и работают намного медленнее. Эти случаи действительно довольно редки; хотя особенно бесит, когда они все же случаются. Вы не должны поставлять неизменно худший продукт, беспокоясь о крайне редких случаях отладки в худшем случае. (Мой не был одним из многих, кто проголосовал против). Я занимался программированием для НАСА; и мы сказали, что как минимум каждую строку кода следует тестировать один раз. Модульное тестирование также может помочь.

CodeLurker 05.10.2018 03:01

На что следует обратить внимание:

Переполнение массива - отладчик Visual Studio вставляет заполнение, которое может предотвратить сбои.

Условия гонки - если у вас задействовано несколько потоков, многие из них появляются только тогда, когда приложение выполняется напрямую.

Связывание - ваша сборка релиза использует правильные библиотеки.

Что стоит попробовать:

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

Привет! Я проголосовал против этого ответа анонимно. Я хочу понять почему?

morechilli 30.08.2013 15:26

Отладка сборок выпуска может быть проблемой из-за оптимизации, изменяющей порядок, в котором строки вашего кода кажутся выполняемыми. Это действительно может сбить с толку!

Один из способов, по крайней мере, сузить проблему - использовать MessageBox () для отображения быстрых операторов, указывающих, в какой части программы находится ваш код («Запуск Foo ()», «Запуск Foo2 ()»); начните размещать их в верхней части функций в той области вашего кода, которую вы подозреваете (что вы делали в то время, когда он разбился?). Когда вы можете сказать, какая функция, измените окна сообщений на блоки кода или даже отдельные строки внутри этой функции, пока вы не сузите ее до нескольких строк. Затем вы можете начать распечатывать значения переменных, чтобы увидеть, в каком состоянии они находятся в момент сбоя.

Он уже пробовал добавить printfs, поэтому окна сообщений не принесут ничего нового на вечеринку.

Greg Whitfield 09.10.2008 12:31

Однажды у меня возникла проблема, когда приложение вело себя так же, как ваше. Это оказалось неприятным переполнением буфера в sprintf. Естественно, это сработало при запуске с подключенным отладчиком. Что я сделал, так это установил фильтр необработанных исключений (SetUnhandledExceptionFilter), в котором я просто блокировал бесконечно (используя WaitForSingleObject на поддельном дескрипторе со значением тайм-аута INFINITE).

Итак, вы могли бы что-то вроде:

long __stdcall MyFilter(EXCEPTION_POINTERS *)
{
    HANDLE hEvt=::CreateEventW(0,1,0,0);
    if (hEvt)
    {
        if (WAIT_FAILED==::WaitForSingleObject(hEvt, INFINITE))
        {
            //log failure
        }
    }

}
// somewhere in your wmain/WinMain:
SetUnhandledExceptionFilter(MyFilter);

Затем я подключил отладчик после того, как ошибка проявилась (программа gui перестала отвечать).

Тогда вы можете либо взять дамп и поработать с ним позже:

.dump /ma path_to_dump_file

Или сразу отладить. Самый простой способ - отследить, где контекст процессора был сохранен механизмом обработки исключений во время выполнения:

s-d esp Range 1003f

Команда будет искать в адресном пространстве стека запись (записи) КОНТЕКСТА при условии длины поиска. Обычно я использую что-то вроде 'l? 10000'. Обратите внимание: не используйте необычно большие числа в качестве записи, которую вы обычно ищете, рядом с фреймом фильтра необработанных исключений. 1003f - это комбинация флагов (я считаю, что она соответствует CONTEXT_FULL), используемая для захвата состояния процессора. Ваш поиск будет выглядеть примерно так:

0:000> s-d esp l1000 1003f
0012c160 0001003f 00000000 00000000 00000000 ?...............

Как только вы получите результаты, используйте адрес в команде cxr:

.cxr 0012c160

Это приведет вас к этому новому КОНТЕКСТУ точно во время сбоя (вы получите именно трассировку стека во время сбоя приложения). Дополнительно используйте:

.exr -1

чтобы узнать, какое именно исключение произошло.

Надеюсь, это поможет.

Ntdll.dll с прикрепленным отладчиком

Одно небольшое различие между запуском программы из IDE или WinDbg и ее запуском из командной строки / рабочего стола заключается в том, что при запуске с подключенным отладчиком (например, IDE или WinDbg) ntdll.dll использует другую реализацию кучи, которая выполняет небольшую проверку. о выделении / освобождении памяти.

Вы можете прочитать соответствующую информацию в неожиданная точка останова пользователя в ntdll.dll. Один из инструментов, который может помочь вам определить проблему, - это PageHeap.exe.

Анализ сбоев

Вы не писали, какой у вас "сбой". Как только программа выйдет из строя и предложит отправить информацию об ошибке в Microsoft, вы сможете щелкнуть по технической информации и проверить хотя бы код исключения, а с некоторыми усилиями вы даже сможете выполнить посмертный анализ (см. Heisenbug: программа WinApi вылетает на некоторых компьютерах) для инструкций)

Попробуйте использовать _CrtCheckMemory (), чтобы узнать, в каком состоянии находится выделенная память. Если все идет хорошо, _CrtCheckMemory возвращает ПРАВДА, иначе ЛОЖНЫЙ.

Вы можете запускать свое программное обеспечение с включенными глобальными флагами (см. Инструменты отладки для Windows). Очень часто это помогает решить проблему.

После многих часов отладки я наконец нашел причину проблемы, которая действительно была вызвана переполнением буфера, вызвавшим однобайтовую разницу:

char *end = static_cast<char*>(attr->data) + attr->dataSize;

Это ошибка заборного столба (ошибка с разницей в одну), которая была исправлена ​​следующим образом:

char *end = static_cast<char*>(attr->data) + attr->dataSize - 1;

Странно было то, что я использовал несколько вызовов _CrtCheckMemory () для различных частей моего кода, и они всегда возвращали 1. Я смог найти источник проблемы, поместив «return false;» вызывает в тестовом случае, а затем, в конечном итоге, методом проб и ошибок определяет, где была ошибка.

Спасибо всем за комментарии - сегодня я много узнал о windbg.exe! :)

Сегодня я отлаживал аналогичную проблему, и _CrtCheckMemory () всегда возвращал 1. Но потом я понял, почему: в режиме Release _CrtCheckMemory # определяется как ((int) 1).

Brian Morearty 16.02.2011 22:28

Заставьте вашу программу генерировать мини-дамп при возникновении исключения, а затем откройте его в отладчике (например, в WinDbg). Ключевые функции, на которые стоит обратить внимание: MiniDumpWriteDump, SetUnhandledExceptionFilter

Vista SP1 имеет действительно хороший генератор аварийных дампов, встроенный в систему. К сожалению, по умолчанию он не включен!

См. Эту статью: http://msdn.microsoft.com/en-us/library/bb787181(VS.85).aspx

Преимущество этого подхода заключается в том, что в уязвимой системе не требуется устанавливать дополнительное программное обеспечение. Возьми его и разорви, детка!

Пока нет ответа, чтобы дать серьезный обзор доступных методов отладки релизных приложений:

  1. Сборки Release и Debug ведут себя по-разному по многим причинам.Вот отличный обзор. Каждое из этих различий может вызвать ошибку в сборке Release, которой нет в сборке Debug.

  2. Наличие отладчика также может изменить поведение программы., как для выпускных, так и для отладочных сборок. Смотрите этот ответ. Короче говоря, по крайней мере, отладчик Visual Studio автоматически использует Debug Heap при подключении к программе. Вы можете отключить отладочную кучу с помощью переменной среды _NO_DEBUG_HEAP. Вы можете указать это либо в свойствах вашего компьютера, либо в настройках проекта в Visual Studio. Это может сделать сбой воспроизводимым с подключенным отладчиком.

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

  3. Если предыдущее решение не работает, вам нужно перехватить необработанное исключение и прикрепить посмертный отладчик в случае сбоя. Вы можете использовать, например, WinDbg для этого, подробности о доступных посмертных отладчиках и их установке на MSDN

  4. Вы можете улучшить свой код обработки исключений, и если это производственное приложение, вам следует:

    а. Установите собственный обработчик завершения с помощью std::set_terminate

    Если вы хотите отладить эту проблему локально, вы можете запустить бесконечный цикл внутри обработчика завершения и вывести текст на консоль, чтобы уведомить вас о вызове std::terminate. Затем подключите отладчик и проверьте стек вызовов. Или вы распечатываете трассировку стека, как описано в этом ответе.

    В производственном приложении вы можете захотеть отправить отчет об ошибке домой, в идеале вместе с небольшим дампом памяти, который позволяет проанализировать проблему, как описано здесь.

    б. Используйте механизм структурированной обработки исключений Microsoft, который позволяет вам перехватывать как аппаратные, так и программные исключения. См. MSDN. Вы можете защитить части своего кода с помощью SEH и использовать тот же подход, что и в а), для отладки проблемы. SEH предоставляет дополнительную информацию о возникшем исключении, которое вы можете использовать при отправке отчета об ошибке из производственного приложения.

Иногда это происходит из-за того, что вы заключили важную операцию в макрос assert. Как вы, возможно, знаете, «assert» оценивает выражения только в режиме отладки.

У меня была эта ошибка, и vs вылетел даже при попытке! Clean! мой проект. Поэтому я вручную удалил файлы obj из каталога Release, и после этого все было нормально.

По моему опыту, это большинство проблем с повреждением памяти.

Например :

char a[8];
memset(&a[0], 0, 16);

: /*use array a doing some thing */

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

Но в выпуске это могло бы привести к сбою.

Для меня слишком утомительно рыться там, где память не ограничена.

Использование некоторых инструментов, таких как Визуальный детектор утечки (windows) или Valgrind (linux), является более разумным выбором.

Отличный способ отладить подобную ошибку - включить оптимизацию для вашей отладочной сборки.

проблема op в том, что он вылетает только в режиме выпуска, а не в том, что отладчик слишком медленный.

reece 01.12.2020 12:49

Я видел много правильных ответов. Однако ничто не помогло мне. В моем случае было неправильное использование Инструкции SSE с невыровненная память. Взгляните на свою математическую библиотеку (если вы ее используете) и попробуйте отключить поддержку SIMD, перекомпилировать и воспроизвести сбой.

Пример:

Проект включает mathfu и использует классы с вектором STL: std :: vector <mathfu :: vec2>. Такое использование, вероятно, вызовет сбой во время создания элемента mathfu :: vec2, поскольку распределитель по умолчанию STL не гарантирует требуемого 16-байтового выравнивания. В этом случае, чтобы подтвердить идею, можно определить #define MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT 1 перед каждым включением mathfu, перекомпилировать в конфигурации Release и снова проверить.

Конфигурации Отлаживать и RelWithDebInfo хорошо работали для моего проекта, но не Выпускать. Причина такого поведения, вероятно, заключается в том, что отладчик обрабатывает запросы на выделение / освобождение и выполняет некоторую учетную запись памяти для проверки и проверки доступа к памяти.

Я испытал ситуацию в средах Visual Studio 2015 и 2017.

Вот случай, который кто-то может счесть поучительным. Он разбился только в выпуске Qt Creator - не при отладке. Я использовал файлы .ini (так как я предпочитаю приложения, которые можно копировать на другие диски, а не те, которые теряют свои настройки в случае повреждения реестра). Это относится к любым приложениям, которые хранят свои настройки в дереве каталогов приложений. Если сборки отладки и выпуска находятся в разных каталогах, у вас также могут быть разные настройки. У меня были отмечены предпочтения в одном, но не в другом. Это оказалось причиной моей аварии. Хорошо, что нашел.

Ненавижу это говорить, но я диагностировал сбой только в MS Visual Studio Community Edition; после установки VS, позволяя моему приложению аварийно завершить работу в Qt Creator и открывая его в отладчике Visual Studio. Хотя в моем приложении Qt не было информации о символах, оказалось, что в библиотеках Qt она была. Это привело меня к обидной линии; так как я мог видеть, какой метод вызывается. (Тем не менее, я думаю, что Qt - это удобный, мощный и кроссплатформенный фреймворк LGPL.)

У меня тоже была эта пробема. В моем случае режим RELEASE содержал msvscrtd.dll в определении компоновщика. Мы удалили его, и проблема решена.

Кроме того, добавление / NODEFAULTLIB в аргументы командной строки компоновщика также решило проблему.

Другие вопросы по теме