Windows CRT и отчеты об утверждении (отмена, повтор, игнорирование) - PullRequest
5 голосов
/ 13 июля 2009

Windows CRT в режиме отладки покажет окно «Прервать, повторить, игнорировать» , если приложение достигает значения assert(false), а иногда оно создается много раз и заполняет мой экран.

Мне бы очень понравилось, если бы ассерт сломался в отладчике и не задавал мне никаких вопросов.

Я изменил флажки отчетов CRT , которые не имели никакого эффекта.

Я также пытался изменить ловушку для отчетов . Он вызывается после 25-30 диалогов «Отмена».

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

Как мне настроить CRT для этого?

Ответы [ 5 ]

6 голосов
/ 20 июля 2009

Это работает (для меня по крайней мере, против 2008 года): (По сути, верните TRUE из подключенной функции)

int __cdecl CrtDbgHook(int nReportType, char* szMsg, int* pnRet)
{
    return TRUE;//Return true - Abort,Retry,Ignore dialog will *not* be displayed
    return FALSE;//Return false - Abort,Retry,Ignore dialog *will be displayed*
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, CrtDbgHook);
    assert(false);
    getch();
    return 1;
}

Вы также можете написать собственное поведение, подобное утверждению (обратите внимание, что при этом отобразится диалоговое окно «Break, Continue»):

#define MYASSERT(x) { if(!(x)) {DbgRaiseAssertionFailure();} }

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
    MYASSERT(false);
    getch();
    return 1;
}

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

3 голосов
/ 21 июля 2009

Ответ Ляо проходит большую часть пути, но я хотел бы предложить вам добавить еще одну вещь к вашему отладочному крюку:

int __cdecl StraightToDebugger(int, char*, int*)
{
  _CrtDbgBreak(); // breaks into debugger
  return TRUE; // handled -- don't process further.
}

В противном случае ваши утверждения просто исчезнут и процесс прекратится.

Проблема с этим подходом состоит в том, что - по крайней мере для моей домашней установки VC Express - отладчик выдает большое сообщение «program.exe вызвало точку останова» вместо обычного сбоя утверждения, поэтому оно может не быть большое улучшение.

1 голос
/ 22 июля 2009

Я не уверен, хотите ли вы, чтобы поведение было для любого assert, или вы просто пытаетесь использовать assert(false) специально как шаблон общего назначения для безоговорочного взлома отладчика в данной строке. Если это первое, посмотрите ответы Ляо и Ким. Если это последнее, тогда вам действительно следует использовать встроенную функцию __debugbreak.

0 голосов
/ 24 июля 2009

Почему бы не использовать Функция DebugBreak ?

Или даже использовать код операции?

#ifdef _X86_
#define BreakPoint()        _asm { int 3h }
#else
#define BreakPoint()        DebugBreak()
#endif

До Visual C ++ 2005 инструкция ,

__asm int 3 не приводил к генерации собственного кода при компиляции с / CLR; компилятор перевел инструкция к перерыву CLR инструкция. Начиная с Visual C ++ 2005, __asm ​​int 3 теперь приводит к генерация нативного кода для функция. Если вы хотите, чтобы функция вызвать точку останова в вашем коде и если вы хотите, чтобы эта функция была скомпилирована в MSIL, используйте __debugbreak.

0 голосов
/ 21 июля 2009

Почему это утверждают? assert (false) выглядит так, как будто код "никогда не случится" был выполнен в CRT. Я был бы напуган, если бы я был тобой. Это всегда на одной линии? Есть ли комментарии по этому поводу?

EDIT: Я имею в виду: assert происходит в коде CRT, потому что есть предположение, что он проверяет, что вы не встречаетесь (возможно, вам удалось связать со смешанной средой выполнения, или вы сделали управляемую сборку C ++, и забыли вручную инициализировать CRT, или вы пытаетесь вызвать LoadLibrary из DllMain или что-то еще, что никогда не должно происходить).

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

Код такой

if(somebadcondition)
{
    assert(false);
    // recovery code
}

буквально означает «эта ветвь кода никогда не должна выполняться».

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