2012-03-10 4 views
2

Я использую _set_invalid_parameter_handler, чтобы переопределить поведение программы по умолчанию, когда функция CRT получает недопустимый параметр, который должен сбой с 0xc0000417 (STATUS_INVALID_CRUNTIME_PARAMETER)._invalid_parameter не получает никакой полезной информации в Release build

Это мой обработчик:

void my_invalid_parameter_handler(
    const wchar_t * expression, 
    const wchar_t * function, 
    const wchar_t * file, 
    unsigned int line, 
    uintptr_t pReserved 
    ) 
{ 
    Log(L"Invalid parameter detected"); 
    Log(L"expression= %s", expression); 
    Log(L"function= %s", function); 
    Log(L"file= %s", file); 
    Log(L"line= %d", line); 
    Log(L"pReserved= %p", pReserved); 
} 

Я хочу, чтобы войти в информацию и отправить сообщение об ошибке. В сборке Debug я получаю полезную информацию с параметрами, но в сборке Release все параметры имеют NULL, что не очень полезно. Есть ли способ добавить полезную информацию в сборках Release?

+0

'все параметры имеют значение NULL, если не используется отладочная версия библиотеки CRT. ' –

+0

Спасибо. Хорошо, что отвечает на мой вопрос. Если вы опубликуете ответ, я выберу его в качестве правильного ответа. – sashoalm

ответ

3

Это явно указано в разделе Замечания MSDN Library article:

Параметры все имеют нулевое значение, если не используется Отладочная версия библиотеки CRT

Причина видна из заголовочный файл crtdefs.h, отредактированный для удобочитаемости:

#ifdef _DEBUG 
# ifndef _CRT_SECURE_INVALID_PARAMETER 
# define _CRT_SECURE_INVALID_PARAMETER(expr) \ 
     ::_invalid_parameter(__STR2WSTR(#expr), _FUNCTIONW__, __FILEW__, __LINE__, 0) 
# endif 

#else 

/* By default, _CRT_SECURE_INVALID_PARAMETER in retail invokes_invalid_parameter_noinfo_noreturn(), 
    * which is marked __declspec(noreturn) and does not return control to the application. Even if 
    * _set_invalid_parameter_handler() is used to set a new invalid parameter handler which does return 
    * control to the application, _invalid_parameter_noinfo_noreturn() will terminate the application and 
    * invoke Watson. You can overwrite the definition of _CRT_SECURE_INVALID_PARAMETER if you need. 
    * 
    * _CRT_SECURE_INVALID_PARAMETER is used in the Standard C++ Libraries and the SafeInt library. 
    */ 
# ifndef _CRT_SECURE_INVALID_PARAMETER 
# define _CRT_SECURE_INVALID_PARAMETER(expr) ::_invalid_parameter_noinfo_noreturn() 
# endif /* _CRT_SECURE_INVALID_PARAMETER */ 
#endif /* _DEBUG */ 

Одна оптимизация слишком много, я бы сказал. Возможность #define _CRT_SECURE_INVALID_PARAMETER сама выглядит привлекательной, но не работает, если вы не перестраиваете CRT самостоятельно. Это не совсем практично.

+0

Просто наткнулся на это. Что было бы более практичным решением? Например. напечатать некоторую информацию об утверждении, более полезную, чем это »2014-11-13 13:33:14 [4548] Утверждение не выполнено: (null) в функции (null) в файле (null) в строке 0" – CouchDeveloper

+0

Ну, _set_invalid_parameter_handler() умеренно более практичным. Не забудьте создать мини-накопитель при вызове обработчика, он вам понадобится. –

+0

Я уже установил этот обработчик, где я печатаю сообщение через регистратор. Кроме того, теперь я регистрирую трассировку стека. Спасибо за совет! ;) – CouchDeveloper