Skip to content

Commit

Permalink
GRASS fatal error longjmp
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed May 15, 2014
1 parent 13f3a8a commit 38fba0c
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 23 deletions.
10 changes: 4 additions & 6 deletions src/providers/grass/CMakeLists.txt
Expand Up @@ -561,12 +561,10 @@ TARGET_LINK_LIBRARIES(grassprovider qgisgrass)
# grass raster provider
#

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

# override default path where built files are put to allow running qgis without installing
# the modules go under libexec subdir
Expand Down
35 changes: 29 additions & 6 deletions src/providers/grass/qgsgrass.cpp
Expand Up @@ -14,6 +14,8 @@
* *
***************************************************************************/

#include <setjmp.h>

#include "qgsgrass.h"

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

jmp_buf QgsGrass::jumper;

int QgsGrass::initialized = 0;

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

if ( fatal )
{
// we have to throw an exception here, otherwise GRASS >= 6.3 will kill our process
throw QgsGrass::Exception( QString::fromUtf8( msg ) );
QgsDebugMsg( "fatal -> longjmp" );
// Exceptions cannot be thrown from here if GRASS lib is not compiled with -fexceptions
//throw QgsGrass::Exception( QString::fromUtf8( msg ) );
lastError = FATAL;

#if (GRASS_VERSION_MAJOR == 7) && (GRASS_VERSION_MINOR == 0)
// G_fatal_error in GRASS 7.0.0beta1 always exists the second time it is called.
if ( QString( GRASS_VERSION_RELEASE_STRING ) == "0beta1" )
{
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 ) );
}
#endif

longjmp( QgsGrass::jumper, 1 );
}
else
{
lastError = WARNING;
}

return 1;
}
Expand Down Expand Up @@ -797,6 +815,7 @@ QStringList GRASS_LIB_EXPORT QgsGrass::vectors( QString mapsetPath )
QStringList GRASS_LIB_EXPORT QgsGrass::vectorLayers( QString gisdbase,
QString location, QString mapset, QString mapName )
{
QgsDebugMsg( QString( "gisdbase = %1 location = %2 mapset = %3 mapName = %4" ).arg( gisdbase ).arg( location ).arg( mapset ).arg( mapName ) );
QStringList list;

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

try
// Vect_open_old_head GRASS is raising fatal error if topo exists but it is in different (older) version.
// It means that even we could open it on level one, it ends with exception,
// but we need level 2 anyway to get list of layers, so it does not matter, only the error message may be misleading.

G_TRY
{
level = Vect_open_old_head( &map, ( char * ) mapName.toUtf8().data(), ( char * ) mapset.toUtf8().data() );
}
catch ( QgsGrass::Exception &e )
G_CATCH( QgsGrass::Exception &e )
{
Q_UNUSED( e );
QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) );
Expand Down Expand Up @@ -1376,11 +1399,11 @@ QgsCoordinateReferenceSystem GRASS_LIB_EXPORT QgsGrass::crsDirect( QString gisdb
const char *oldlocale = setlocale( LC_NUMERIC, NULL );
setlocale( LC_NUMERIC, "C" );

try
G_TRY
{
G_get_default_window( &cellhd );
}
catch ( QgsGrass::Exception &e )
G_CATCH( QgsGrass::Exception &e )
{
Q_UNUSED( e );
setlocale( LC_NUMERIC, oldlocale );
Expand Down
22 changes: 19 additions & 3 deletions src/providers/grass/qgsgrass.h
Expand Up @@ -16,9 +16,12 @@
#ifndef QGSGRASS_H
#define QGSGRASS_H

#include <setjmp.h>

// GRASS header files
extern "C"
{
#include <grass/version.h>
#include <grass/gis.h>
#include <grass/form.h>
}
Expand All @@ -34,12 +37,22 @@ extern "C"
class QgsCoordinateReferenceSystem;
class QgsRectangle;

// Make the release string because it may be for example 0beta1
#define STR(x) #x
#define EXPAND(x) STR(x)
#define GRASS_VERSION_RELEASE_STRING EXPAND( GRASS_VERSION_RELEASE )

#define G_TRY try { if( !setjmp( QgsGrass::jumper ) )
#define G_CATCH else { throw QgsGrass::Exception( QgsGrass::errorMessage() ); } } catch

/*!
Methods for C library initialization and error handling.
*/
class QgsGrass
{
public:
static jmp_buf jumper; // used to get back from fatal error

// This does not work (gcc/Linux), such exception cannot be caught
// so I have enabled the old version, if you are able to fix it, please
// check first if it realy works, i.e. can be caught!
Expand Down Expand Up @@ -93,9 +106,12 @@ class QgsGrass
static GRASS_LIB_EXPORT void setMapset( QString gisdbase, QString location, QString mapset );

//! Error codes returned by error()
enum GERROR { OK, /*!< OK. No error. */
WARNING /*!< Warning, non fatal error. Should be printed by application. */
};
enum GERROR
{
OK, /*!< OK. No error. */
WARNING, /*!< Warning, non fatal error. Should be printed by application. */
FATAL /*!< Fatal error */
};

//! Map type
enum MapType { None, Raster, Vector, Region };
Expand Down
16 changes: 8 additions & 8 deletions src/providers/grass/qgsgrassprovider.cpp
Expand Up @@ -799,13 +799,13 @@ int QgsGrassProvider::openMap( QString gisdbase, QString location, QString mapse

// Do we have topology and cidx (level2)
int level = 2;
try
G_TRY
{
Vect_set_open_level( 2 );
Vect_open_old_head( map.map, mapName.toUtf8().data(), mapset.toUtf8().data() );
Vect_close( map.map );
}
catch ( QgsGrass::Exception &e )
G_CATCH( QgsGrass::Exception &e )
{
Q_UNUSED( e );
QgsDebugMsg( QString( "Cannot open GRASS vector head on level2: %1" ).arg( e.what() ) );
Expand All @@ -823,12 +823,12 @@ int QgsGrassProvider::openMap( QString gisdbase, QString location, QString mapse
}

// Open vector
try
G_TRY
{
Vect_set_open_level( level );
Vect_open_old( map.map, mapName.toUtf8().data(), mapset.toUtf8().data() );
}
catch ( QgsGrass::Exception &e )
G_CATCH( QgsGrass::Exception &e )
{
Q_UNUSED( e );
QgsDebugMsg( QString( "Cannot open GRASS vector: %1" ).arg( e.what() ) );
Expand All @@ -837,7 +837,7 @@ int QgsGrassProvider::openMap( QString gisdbase, QString location, QString mapse

if ( level == 1 )
{
try
G_TRY
{
#if defined(GRASS_VERSION_MAJOR) && defined(GRASS_VERSION_MINOR) && \
( ( GRASS_VERSION_MAJOR == 6 && GRASS_VERSION_MINOR >= 4 ) || GRASS_VERSION_MAJOR > 6 )
Expand All @@ -846,7 +846,7 @@ int QgsGrassProvider::openMap( QString gisdbase, QString location, QString mapse
Vect_build( map.map, stderr );
#endif
}
catch ( QgsGrass::Exception &e )
G_CATCH( QgsGrass::Exception &e )
{
Q_UNUSED( e );
QgsDebugMsg( QString( "Cannot build topology: %1" ).arg( e.what() ) );
Expand Down Expand Up @@ -891,12 +891,12 @@ void QgsGrassProvider::updateMap( int mapId )
map->lastAttributesModified = di.lastModified();

// Reopen vector
try
G_TRY
{
Vect_set_open_level( 2 );
Vect_open_old( map->map, map->mapName.toUtf8().data(), map->mapset.toUtf8().data() );
}
catch ( QgsGrass::Exception &e )
G_CATCH( QgsGrass::Exception &e )
{
Q_UNUSED( e );
QgsDebugMsg( QString( "Cannot reopen GRASS vector: %1" ).arg( e.what() ) );
Expand Down
2 changes: 2 additions & 0 deletions src/providers/grass/qgsgrassprovidermodule.cpp
Expand Up @@ -79,6 +79,8 @@ bool QgsGrassMapsetItem::isMapset( QString path )

QVector<QgsDataItem*> QgsGrassMapsetItem::createChildren()
{
QgsDebugMsg( "Entered" );

QVector<QgsDataItem*> items;

QStringList vectorNames = QgsGrass::vectors( mPath );
Expand Down
4 changes: 4 additions & 0 deletions src/providers/grass/qgsgrassrasterprovider.h
Expand Up @@ -22,7 +22,11 @@

extern "C"
{
#include <grass/version.h>
#include <grass/gis.h>
#if GRASS_VERSION_MAJOR > 6
#include <grass/raster.h>
#endif
}

#include "qgscoordinatereferencesystem.h"
Expand Down

0 comments on commit 38fba0c

Please sign in to comment.