From 61e3fe93a3b78f9cce3c82a539a83512c5258399 Mon Sep 17 00:00:00 2001 From: jef Date: Tue, 20 May 2008 22:09:40 +0000 Subject: [PATCH] fix grass crash: setlocale to "C" in getSRS() and catch fatal errors (probably needed at much more places). git-svn-id: http://svn.osgeo.org/qgis/trunk@8476 c8812cc2-4d05-0410-92ff-de0c093fc19c --- src/plugins/grass/qgsgrassselect.cpp | 1 + src/providers/grass/qgsgrass.cpp | 23 ++++++++++++++++++++--- src/providers/grass/qgsgrass.h | 2 ++ src/providers/grass/qgsgrassprovider.cpp | 20 +++++++++++++++++++- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/plugins/grass/qgsgrassselect.cpp b/src/plugins/grass/qgsgrassselect.cpp index acd437d2f60..6026d098792 100644 --- a/src/plugins/grass/qgsgrassselect.cpp +++ b/src/plugins/grass/qgsgrassselect.cpp @@ -397,6 +397,7 @@ QStringList QgsGrassSelect::vectorLayers ( QString gisdbase, level = Vect_open_old_head (&map, (char *) mapName.ascii(), (char *) mapset.ascii()); } + QgsGrass::clearErrorEnv(); if ( QgsGrass::getError() == QgsGrass::FATAL ) { std::cerr << "Cannot open GRASS vector: " << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl; diff --git a/src/providers/grass/qgsgrass.cpp b/src/providers/grass/qgsgrass.cpp index a949be43e47..2fe1195af60 100644 --- a/src/providers/grass/qgsgrass.cpp +++ b/src/providers/grass/qgsgrass.cpp @@ -16,6 +16,7 @@ /* $Id$ */ #include +#include #include "QString" #include "q3process.h" @@ -375,6 +376,7 @@ QString QgsGrass::mGisrc; QString QgsGrass::mTmp; jmp_buf QgsGrass::mFatalErrorEnv; +bool QgsGrass::mFatalErrorEnvActive=false; int QgsGrass::error_routine ( char *msg, int fatal) { @@ -383,15 +385,21 @@ int QgsGrass::error_routine ( char *msg, int fatal) int QgsGrass::error_routine ( const char *msg, int fatal) { - std::cerr << "error_routine (fatal = " << fatal << "): " << msg << std::endl; + QgsDebugMsg(QString("error_routine (fatal = %1): %2").arg(fatal).arg(msg)); error_message = msg; if ( fatal ) - { + { error = FATAL; // we have to do a long jump here, otherwise GRASS >= 6.3 will kill our process - longjmp(mFatalErrorEnv, 1); + if( mFatalErrorEnvActive ) + longjmp(mFatalErrorEnv, 1); + else + { + QMessageBox::warning( 0, QObject::tr("Uncatched fatal GRASS error"), msg ); + abort(); + } } else error = WARNING; @@ -416,9 +424,18 @@ QString GRASS_EXPORT QgsGrass::getErrorMessage ( void ) jmp_buf GRASS_EXPORT &QgsGrass::fatalErrorEnv() { + if(mFatalErrorEnvActive) + QgsDebugMsg("fatal error environment already active."); + mFatalErrorEnvActive = true; return mFatalErrorEnv; } +void GRASS_EXPORT QgsGrass::clearErrorEnv() +{ + if(!mFatalErrorEnvActive) + QgsDebugMsg("fatal error environment already deactive."); + mFatalErrorEnvActive = false; +} QString GRASS_EXPORT QgsGrass::openMapset ( QString gisdbase, QString location, QString mapset ) { diff --git a/src/providers/grass/qgsgrass.h b/src/providers/grass/qgsgrass.h index d84ff684e5b..781b769c9d3 100644 --- a/src/providers/grass/qgsgrass.h +++ b/src/providers/grass/qgsgrass.h @@ -155,6 +155,7 @@ public: static GRASS_EXPORT QString versionString(); static GRASS_EXPORT jmp_buf& fatalErrorEnv(); + static GRASS_EXPORT void clearErrorEnv(); private: @@ -184,6 +185,7 @@ private: // Context saved before a call to routine that can produce a fatal error static jmp_buf mFatalErrorEnv; + static bool mFatalErrorEnvActive; }; #endif // QGSGRASS_H diff --git a/src/providers/grass/qgsgrassprovider.cpp b/src/providers/grass/qgsgrassprovider.cpp index dbbec0f4af1..b67f58c99a3 100644 --- a/src/providers/grass/qgsgrassprovider.cpp +++ b/src/providers/grass/qgsgrassprovider.cpp @@ -1250,8 +1250,24 @@ QgsSpatialRefSys QgsGrassProvider::getSRS() struct Cell_head cellhd; + QgsGrass::resetError(); QgsGrass::setLocation ( mGisdbase, mLocation ); - G_get_default_window(&cellhd); + + char *oldlocale = setlocale(LC_ALL, NULL); + setlocale(LC_ALL, "C"); + + if ( setjmp(QgsGrass::fatalErrorEnv()) == 0 ) + { + G_get_default_window(&cellhd); + } + QgsGrass::clearErrorEnv(); + + if ( QgsGrass::getError() == QgsGrass::FATAL ) { + setlocale(LC_ALL, oldlocale); + QgsDebugMsg(QString("Cannot get default window: %1").arg(QgsGrass::getErrorMessage())); + return QgsSpatialRefSys(); + } + if (cellhd.proj != PROJECTION_XY) { struct Key_Value *projinfo = G_get_projinfo(); struct Key_Value *projunits = G_get_projunits(); @@ -1260,6 +1276,8 @@ QgsSpatialRefSys QgsGrassProvider::getSRS() free ( wkt); } + setlocale(LC_ALL, oldlocale); + QgsSpatialRefSys srs; srs.createFromWkt(WKT);