【MSVC】_invalid_parameter和_invoke_watson

最近遇到一个崩溃问题,崩溃在CRT中,最后调用的函数是_invoke_watson。调用关系大概如下:

_invoke_watson
_invalid_parameter
_invalid_parameter_noinfo_noreturn
memcpy_s

虽然看的出来这个是memcpy参数不对导致的崩溃,但是这几个之前没见过的函数成功吸引了我的注意!

这一系列的函数用在windows CRT中处理函数的无效传参。_invalid_parameter的函数原型如下:

extern "C" void __cdecl
_invalid_parameter(
    wchar_t const* const expression,
    wchar_t const* const function_name,
    wchar_t const* const file_name,
    unsigned int   const line_number,
    uintptr_t      const reserved);

它会调用处理函数(默认为_invoke_watson),比如结束程序等。_invalid_parameter_noinfo_noreturn和_invoke_watson不会返回调用者函数。

CRT支持设置自定义像_invoke_watson这样的处理函数,_set_invalid_parameter_handler为全局的,_set_thread_local_invalid_parameter_handler只是针对当前线程的:

_invalid_parameter_handler _set_invalid_parameter_handler(
   _invalid_parameter_handler pNew
);
_invalid_parameter_handler _set_thread_local_invalid_parameter_handler(
   _invalid_parameter_handler pNew
);
_invalid_parameter_handler _get_invalid_parameter_handler(void);
_invalid_parameter_handler _get_thread_local_invalid_parameter_handler(void);

自定义的处理函数原型如下:

void _invalid_parameter(
   const wchar_t * expression,
   const wchar_t * function,
   const wchar_t * file,
   unsigned int line,
   uintptr_t pReserved
);

一个例子:

#include <iostream>
#include <stdlib.h>
using namespace std;

void globalInvalidParameterHandler(const wchar_t* expression,
                                   const wchar_t* function,
                                   const wchar_t* file,
                                   unsigned int line,
                                   uintptr_t pReserved) {
    printf("invalid param!\n");
    abort();
}

void handleA(int size) {
    if(size <= 0) {
        _invalid_parameter_noinfo();
    }
}

int main(int argc, char* argv[]) {
    _invalid_parameter_handler oldHandler;
    oldHandler = _set_invalid_parameter_handler(globalInvalidParameterHandler);

    handleA(0);

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tkorays/p/10540462.html
今日推荐