Skip to content

Commit 77dfd46

Browse files
author
jef
committed
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/qgis@8476 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 0c9b20e commit 77dfd46

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

src/plugins/grass/qgsgrassselect.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ QStringList QgsGrassSelect::vectorLayers ( QString gisdbase,
397397
level = Vect_open_old_head (&map, (char *) mapName.ascii(),
398398
(char *) mapset.ascii());
399399
}
400+
QgsGrass::clearErrorEnv();
400401

401402
if ( QgsGrass::getError() == QgsGrass::FATAL ) {
402403
std::cerr << "Cannot open GRASS vector: " << QgsGrass::getErrorMessage().toLocal8Bit().data() << std::endl;

src/providers/grass/qgsgrass.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
/* $Id$ */
1717

1818
#include <iostream>
19+
#include <qgslogger.h>
1920

2021
#include "QString"
2122
#include "q3process.h"
@@ -375,6 +376,7 @@ QString QgsGrass::mGisrc;
375376
QString QgsGrass::mTmp;
376377

377378
jmp_buf QgsGrass::mFatalErrorEnv;
379+
bool QgsGrass::mFatalErrorEnvActive=false;
378380

379381
int QgsGrass::error_routine ( char *msg, int fatal)
380382
{
@@ -383,15 +385,21 @@ int QgsGrass::error_routine ( char *msg, int fatal)
383385

384386
int QgsGrass::error_routine ( const char *msg, int fatal)
385387
{
386-
std::cerr << "error_routine (fatal = " << fatal << "): " << msg << std::endl;
388+
QgsDebugMsg(QString("error_routine (fatal = %1): %2").arg(fatal).arg(msg));
387389

388390
error_message = msg;
389391

390392
if ( fatal )
391-
{
393+
{
392394
error = FATAL;
393395
// we have to do a long jump here, otherwise GRASS >= 6.3 will kill our process
394-
longjmp(mFatalErrorEnv, 1);
396+
if( mFatalErrorEnvActive )
397+
longjmp(mFatalErrorEnv, 1);
398+
else
399+
{
400+
QMessageBox::warning( 0, QObject::tr("Uncatched fatal GRASS error"), msg );
401+
abort();
402+
}
395403
}
396404
else
397405
error = WARNING;
@@ -416,9 +424,18 @@ QString GRASS_EXPORT QgsGrass::getErrorMessage ( void )
416424

417425
jmp_buf GRASS_EXPORT &QgsGrass::fatalErrorEnv()
418426
{
427+
if(mFatalErrorEnvActive)
428+
QgsDebugMsg("fatal error environment already active.");
429+
mFatalErrorEnvActive = true;
419430
return mFatalErrorEnv;
420431
}
421432

433+
void GRASS_EXPORT QgsGrass::clearErrorEnv()
434+
{
435+
if(!mFatalErrorEnvActive)
436+
QgsDebugMsg("fatal error environment already deactive.");
437+
mFatalErrorEnvActive = false;
438+
}
422439

423440
QString GRASS_EXPORT QgsGrass::openMapset ( QString gisdbase, QString location, QString mapset )
424441
{

src/providers/grass/qgsgrass.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ class QgsGrass {
155155
static GRASS_EXPORT QString versionString();
156156

157157
static GRASS_EXPORT jmp_buf& fatalErrorEnv();
158+
static GRASS_EXPORT void clearErrorEnv();
158159

159160

160161
private:
@@ -184,6 +185,7 @@ class QgsGrass {
184185

185186
// Context saved before a call to routine that can produce a fatal error
186187
static jmp_buf mFatalErrorEnv;
188+
static bool mFatalErrorEnvActive;
187189
};
188190

189191
#endif // QGSGRASS_H

src/providers/grass/qgsgrassprovider.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1250,8 +1250,24 @@ QgsSpatialRefSys QgsGrassProvider::getSRS()
12501250

12511251
struct Cell_head cellhd;
12521252

1253+
QgsGrass::resetError();
12531254
QgsGrass::setLocation ( mGisdbase, mLocation );
1254-
G_get_default_window(&cellhd);
1255+
1256+
char *oldlocale = setlocale(LC_ALL, NULL);
1257+
setlocale(LC_ALL, "C");
1258+
1259+
if ( setjmp(QgsGrass::fatalErrorEnv()) == 0 )
1260+
{
1261+
G_get_default_window(&cellhd);
1262+
}
1263+
QgsGrass::clearErrorEnv();
1264+
1265+
if ( QgsGrass::getError() == QgsGrass::FATAL ) {
1266+
setlocale(LC_ALL, oldlocale);
1267+
QgsDebugMsg(QString("Cannot get default window: %1").arg(QgsGrass::getErrorMessage()));
1268+
return QgsSpatialRefSys();
1269+
}
1270+
12551271
if (cellhd.proj != PROJECTION_XY) {
12561272
struct Key_Value *projinfo = G_get_projinfo();
12571273
struct Key_Value *projunits = G_get_projunits();
@@ -1260,6 +1276,8 @@ QgsSpatialRefSys QgsGrassProvider::getSRS()
12601276
free ( wkt);
12611277
}
12621278

1279+
setlocale(LC_ALL, oldlocale);
1280+
12631281
QgsSpatialRefSys srs;
12641282
srs.createFromWkt(WKT);
12651283

0 commit comments

Comments
 (0)