CPLSetErrorHandlerEx函数Bug

CPLSetErrorHandlerEx(gdal/gdal/port/cpl_error.cpp,当前github中代码)当前函数实现如下

CPLErrorHandler CPL_STDCALL
CPLSetErrorHandlerEx( CPLErrorHandler pfnErrorHandlerNew, void* pUserData )
{
    CPLErrorContext *psCtx = CPLGetErrorContext();
    if( psCtx == nullptr || IS_PREFEFINED_ERROR_CTX(psCtx) )
    {
        fprintf(stderr, "CPLSetErrorHandlerEx() failed.
");
        return nullptr;
    }

    if( psCtx->psHandlerStack != nullptr )
    {
        CPLDebug( "CPL",
                  "CPLSetErrorHandler() called with an error handler on "
                  "the local stack.  New error handler will not be used "
                  "immediately." );
    }

    CPLErrorHandler pfnOldHandler = nullptr;
    {
        CPLMutexHolderD( &hErrorMutex );

        pfnOldHandler = pfnErrorHandler;

        if( pfnErrorHandler == nullptr )
            pfnErrorHandler = CPLDefaultErrorHandler;
        else
            pfnErrorHandler = pfnErrorHandlerNew;

        pErrorHandlerUserData = pUserData;
    }

    return pfnOldHandler;
}

这里 if( pfnErrorHandler == nullptr )这一句判断应该改为 if( pfnErrorHandlerNew== nullptr )
否则调用过一次CPLSetErrorHandlerEx(NULL,NULL)后将无法再设置新的错误处理函数,必须再次调用使之变为CPLDefaultErrorHandler后方能重新设置(如果没有重新设置,程序将出现段错误)。
自己编译GDAL的时候可以改过了,或者调用的时候传参别传错了即可。
对于这个问题,我已经提交给GDAL开发者了,这个问题已经修正了。CPLSetErrorHandler(): avoid later crashes when passing a null callback.

原文地址:https://www.cnblogs.com/oloroso/p/8422758.html