Skip to content

Commit 38fba0c

Browse files
committedMay 15, 2014
GRASS fatal error longjmp
1 parent 13f3a8a commit 38fba0c

File tree

6 files changed

+66
-23
lines changed

6 files changed

+66
-23
lines changed
 

‎src/providers/grass/CMakeLists.txt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -561,12 +561,10 @@ TARGET_LINK_LIBRARIES(grassprovider qgisgrass)
561561
# grass raster provider
562562
#
563563

564-
IF (GRASS_MAJOR_VERSION LESS 7 )
565-
QT4_WRAP_CPP(GRASS_RASTERPROVIDER_MOC_SRCS qgsgrassrasterprovider.h)
566-
ADD_LIBRARY(grassrasterprovider MODULE qgsgrassrasterprovider.cpp ${GRASS_RASTERPROVIDER_MOC_SRCS})
567-
SET_TARGET_PROPERTIES(grassrasterprovider PROPERTIES COMPILE_FLAGS "\"-DGRASS_EXPORT=${DLLEXPORT}\" \"-DGRASS_LIB_EXPORT=${DLLIMPORT}\"" )
568-
TARGET_LINK_LIBRARIES(grassrasterprovider qgisgrass qgis_core)
569-
ENDIF (GRASS_MAJOR_VERSION LESS 7 )
564+
QT4_WRAP_CPP(GRASS_RASTERPROVIDER_MOC_SRCS qgsgrassrasterprovider.h)
565+
ADD_LIBRARY(grassrasterprovider MODULE qgsgrassrasterprovider.cpp ${GRASS_RASTERPROVIDER_MOC_SRCS})
566+
SET_TARGET_PROPERTIES(grassrasterprovider PROPERTIES COMPILE_FLAGS "\"-DGRASS_EXPORT=${DLLEXPORT}\" \"-DGRASS_LIB_EXPORT=${DLLIMPORT}\"" )
567+
TARGET_LINK_LIBRARIES(grassrasterprovider qgisgrass qgis_core)
570568

571569
# override default path where built files are put to allow running qgis without installing
572570
# the modules go under libexec subdir

‎src/providers/grass/qgsgrass.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* *
1515
***************************************************************************/
1616

17+
#include <setjmp.h>
18+
1719
#include "qgsgrass.h"
1820

1921
#include "qgslogger.h"
@@ -399,6 +401,8 @@ void QgsGrass::setMapset( QString gisdbase, QString location, QString mapset )
399401
for ( int i = 0; ms[i]; i++ ) G_add_mapset_to_search_path( ms[i] );
400402
}
401403

404+
jmp_buf QgsGrass::jumper;
405+
402406
int QgsGrass::initialized = 0;
403407

404408
bool QgsGrass::active = 0;
@@ -432,11 +436,25 @@ int QgsGrass::error_routine( const char *msg, int fatal )
432436

433437
if ( fatal )
434438
{
435-
// we have to throw an exception here, otherwise GRASS >= 6.3 will kill our process
436-
throw QgsGrass::Exception( QString::fromUtf8( msg ) );
439+
QgsDebugMsg( "fatal -> longjmp" );
440+
// Exceptions cannot be thrown from here if GRASS lib is not compiled with -fexceptions
441+
//throw QgsGrass::Exception( QString::fromUtf8( msg ) );
442+
lastError = FATAL;
443+
444+
#if (GRASS_VERSION_MAJOR == 7) && (GRASS_VERSION_MINOR == 0)
445+
// G_fatal_error in GRASS 7.0.0beta1 always exists the second time it is called.
446+
if ( QString( GRASS_VERSION_RELEASE_STRING ) == "0beta1" )
447+
{
448+
QMessageBox::warning( 0, QObject::tr( "Warning" ), QObject::tr( "Fatal error occurred in GRASS library. QGIS gets over the error but any next fatal error will cause QGIS exit without warning. This is a problem of GRASS 7.0.0beta1 and hopefully will be fixed in higher GRASS versions. Error message: %1" ).arg( msg ) );
449+
}
450+
#endif
451+
452+
longjmp( QgsGrass::jumper, 1 );
437453
}
438454
else
455+
{
439456
lastError = WARNING;
457+
}
440458

441459
return 1;
442460
}
@@ -797,6 +815,7 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectors( QString mapsetPath )
797815
QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
798816
QString location, QString mapset, QString mapName )
799817
{
818+
QgsDebugMsg( QString( "gisdbase = %1 location = %2 mapset = %3 mapName = %4" ).arg( gisdbase ).arg( location ).arg( mapset ).arg( mapName ) );
800819
QStringList list;
801820

802821
// Set location
@@ -808,11 +827,15 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
808827
struct Map_info map;
809828
int level = -1;
810829

811-
try
830+
// Vect_open_old_head GRASS is raising fatal error if topo exists but it is in different (older) version.
831+
// It means that even we could open it on level one, it ends with exception,
832+
// but we need level 2 anyway to get list of layers, so it does not matter, only the error message may be misleading.
833+
834+
G_TRY
812835
{
813836
level = Vect_open_old_head( &map, ( char * ) mapName.toUtf8().data(), ( char * ) mapset.toUtf8().data() );
814837
}
815-
catch ( QgsGrass::Exception &e )
838+
G_CATCH( QgsGrass::Exception &e )
816839
{
817840
Q_UNUSED( e );
818841
QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) );
@@ -1376,11 +1399,11 @@ QgsCoordinateReferenceSystem GRASS_LIB_EXPORT QgsGrass::crsDirect( QString gisdb
13761399
const char *oldlocale = setlocale( LC_NUMERIC, NULL );
13771400
setlocale( LC_NUMERIC, "C" );
13781401

1379-
try
1402+
G_TRY
13801403
{
13811404
G_get_default_window( &cellhd );
13821405
}
1383-
catch ( QgsGrass::Exception &e )
1406+
G_CATCH( QgsGrass::Exception &e )
13841407
{
13851408
Q_UNUSED( e );
13861409
setlocale( LC_NUMERIC, oldlocale );

‎src/providers/grass/qgsgrass.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
#ifndef QGSGRASS_H
1717
#define QGSGRASS_H
1818

19+
#include <setjmp.h>
20+
1921
// GRASS header files
2022
extern "C"
2123
{
24+
#include <grass/version.h>
2225
#include <grass/gis.h>
2326
#include <grass/form.h>
2427
}
@@ -34,12 +37,22 @@ extern "C"
3437
class QgsCoordinateReferenceSystem;
3538
class QgsRectangle;
3639

40+
// Make the release string because it may be for example 0beta1
41+
#define STR(x) #x
42+
#define EXPAND(x) STR(x)
43+
#define GRASS_VERSION_RELEASE_STRING EXPAND( GRASS_VERSION_RELEASE )
44+
45+
#define G_TRY try { if( !setjmp( QgsGrass::jumper ) )
46+
#define G_CATCH else { throw QgsGrass::Exception( QgsGrass::errorMessage() ); } } catch
47+
3748
/*!
3849
Methods for C library initialization and error handling.
3950
*/
4051
class QgsGrass
4152
{
4253
public:
54+
static jmp_buf jumper; // used to get back from fatal error
55+
4356
// This does not work (gcc/Linux), such exception cannot be caught
4457
// so I have enabled the old version, if you are able to fix it, please
4558
// check first if it realy works, i.e. can be caught!
@@ -93,9 +106,12 @@ class QgsGrass
93106
static GRASS_LIB_EXPORT void setMapset( QString gisdbase, QString location, QString mapset );
94107

95108
//! Error codes returned by error()
96-
enum GERROR { OK, /*!< OK. No error. */
97-
WARNING /*!< Warning, non fatal error. Should be printed by application. */
98-
};
109+
enum GERROR
110+
{
111+
OK, /*!< OK. No error. */
112+
WARNING, /*!< Warning, non fatal error. Should be printed by application. */
113+
FATAL /*!< Fatal error */
114+
};
99115

100116
//! Map type
101117
enum MapType { None, Raster, Vector, Region };

‎src/providers/grass/qgsgrassprovider.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -799,13 +799,13 @@ int QgsGrassProvider::openMap( QString gisdbase, QString location, QString mapse
799799

800800
// Do we have topology and cidx (level2)
801801
int level = 2;
802-
try
802+
G_TRY
803803
{
804804
Vect_set_open_level( 2 );
805805
Vect_open_old_head( map.map, mapName.toUtf8().data(), mapset.toUtf8().data() );
806806
Vect_close( map.map );
807807
}
808-
catch ( QgsGrass::Exception &e )
808+
G_CATCH( QgsGrass::Exception &e )
809809
{
810810
Q_UNUSED( e );
811811
QgsDebugMsg( QString( "Cannot open GRASS vector head on level2: %1" ).arg( e.what() ) );
@@ -823,12 +823,12 @@ int QgsGrassProvider::openMap( QString gisdbase, QString location, QString mapse
823823
}
824824

825825
// Open vector
826-
try
826+
G_TRY
827827
{
828828
Vect_set_open_level( level );
829829
Vect_open_old( map.map, mapName.toUtf8().data(), mapset.toUtf8().data() );
830830
}
831-
catch ( QgsGrass::Exception &e )
831+
G_CATCH( QgsGrass::Exception &e )
832832
{
833833
Q_UNUSED( e );
834834
QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) );
@@ -837,7 +837,7 @@ int QgsGrassProvider::openMap( QString gisdbase, QString location, QString mapse
837837

838838
if ( level == 1 )
839839
{
840-
try
840+
G_TRY
841841
{
842842
#if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \
843843
( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR >= 4 ) || GRASS_VERSION_MAJOR > 6 )
@@ -846,7 +846,7 @@ int QgsGrassProvider::openMap( QString gisdbase, QString location, QString mapse
846846
Vect_build( map.map, stderr );
847847
#endif
848848
}
849-
catch ( QgsGrass::Exception &e )
849+
G_CATCH( QgsGrass::Exception &e )
850850
{
851851
Q_UNUSED( e );
852852
QgsDebugMsg( QString( "Cannot build topology: %1" ).arg( e.what() ) );
@@ -891,12 +891,12 @@ void QgsGrassProvider::updateMap( int mapId )
891891
map->lastAttributesModified = di.lastModified();
892892

893893
// Reopen vector
894-
try
894+
G_TRY
895895
{
896896
Vect_set_open_level( 2 );
897897
Vect_open_old( map->map, map->mapName.toUtf8().data(), map->mapset.toUtf8().data() );
898898
}
899-
catch ( QgsGrass::Exception &e )
899+
G_CATCH( QgsGrass::Exception &e )
900900
{
901901
Q_UNUSED( e );
902902
QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( e.what() ) );

‎src/providers/grass/qgsgrassprovidermodule.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ bool QgsGrassMapsetItem::isMapset( QString path )
7979

8080
QVector<QgsDataItem*> QgsGrassMapsetItem::createChildren()
8181
{
82+
QgsDebugMsg( "Entered" );
83+
8284
QVector<QgsDataItem*> items;
8385

8486
QStringList vectorNames = QgsGrass::vectors( mPath );

‎src/providers/grass/qgsgrassrasterprovider.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@
2222

2323
extern "C"
2424
{
25+
#include <grass/version.h>
2526
#include <grass/gis.h>
27+
#if GRASS_VERSION_MAJOR > 6
28+
#include <grass/raster.h>
29+
#endif
2630
}
2731

2832
#include "qgscoordinatereferencesystem.h"

0 commit comments

Comments
 (0)
Please sign in to comment.