Exceptions werden nicht gefangen



  • Hallo,

    ich habe in etwa folgenden C++ Code

    try{
      Klasse1 klasse;
      try{
        klasse.funktion()
      }
      catch(std::exception e){
        // gib error aus
      }
    }
    catch(std::exception e){
      // gib error aus
    }
    

    Wenn ich das innere catch weg lasse, fängt der äußere catch Block meine Exception nicht, obwohl diese Typgleich sind. Der innere jedoch fängt diese korrekt. Einziger Unterschied: in der äußeren steckt halt noch der Konstruktor mit drin, aber der wirft selbst keine Exception (schon getestet).

    Woran könnte's liegen?



  • Bitte sehr, gern geschehen. Jetzt kann man es entziffern. "Wo sind wir denn gewesen ..."

    try
    {
    	Klasse1 klasse;
    
    	try
    	{
    		klasse.funktion()
    	}
    	catch(std::exception e)
    	{
    		// gib error aus
    	}
    }
    catch(std::exception e)
    {
    	// gib error aus
    }
    

  • Administrator

    Entziffern konnte man es auch vorher.

    Allerdings zwei andere Dinge:
    1. Ein ausführbares Minimalbeispiel wäre hier sehr hilfreich. Kann unter Umständen sogar dir helfen, den Fehler zu finden.
    2. Man fängt eigentlich Referenzen und nicht Kopien.

    Grüssli



  • Danke für deine Antwort, das mit den Referenzen wusst ich noch nicht. Werd ich beachten.

    Das mit dem ausführbaren Minibeispiel ist nicht so einfach, da die Klasse relativ komplex ist:

    #include <exception>
    #include <iostream>
    
    class testMe{
     public:
      testMe();
      void funktion(){
        throw std::exception;
      }
    };
    
    int main(int argc, char** argv){
      try{
        testMe tester;
        try{
          tester.funktion();
        }
        catch(std::exception &e){
          std::cerr << "Exception gefangen" << std::endl;
        }
      }
      catch(std::exception &f){
        std::cout << "Exception gefangen" << std::endl;
      }
    }
    

    Das wäre es denke ich minimal, um zu verstehen was intern abgeht. Zu Testzwecken habe ich meiner wirklichen Funktion wirklich ein derartiges throw an die erste Zeile gestellt, es hängt also nicht vom Inhalt der Funktion ab.

    Wenn ich das gleiche (throw an die erste Zeile) allerdings innerhalb des Konstruktors selbst mache, funktioniert es (der äußere Block fängt die Exception). Hilft dir das?


  • Mod

    Wenn man die Syntaxfehler in deinem Beispiel korrigiert, dann funktioniert das einwandfrei. Gib uns bitte wirklich mal 1:1 ein Minimalbeispiel von dem, was bei dir nicht funktioniert.



  • main.cpp

    extern "C"{
    	#include <libavformat/avformat.h>
    }
    
    #include "types.h"
    
    #include <iostream>
    #include <cstdlib>
    #include <stdexcept>
    
    #include "openCLProgram.h"
    
    using namespace GRAVID;
    
    int main(int argc, char** argv){
    	try{
    		OpenCLProgram tester;
    		try{
    		tester.loadProgram("src/opencl/kernels/colorFilters.cl","grayFilter");
    		}
    		catch(std::logic_error e){
    			std::cerr << e.what() << std::endl;
    		}
    	}
    	catch(std::logic_error e){
    		std::cerr << e.what() << std::endl;
    		exit(-1);
    	}
    

    OpenCLProgram.h

    #ifndef OPENCLPROGRAM_H_
    #define OPENCLPROGRAM_H_
    
    #include <CL/cl.h>
    #include <stdexcept>
    #include <string>
    
    #include "types.h"
    
    namespace GRAVID{
    	class OpenCLProgram{
    		private:
    			// for opencl return codes
    			cl_int errorCode;
    
    			// the number of OpenCL capable platforms
    			cl_uint nb_platforms;
    			// the available platform ids
    			cl_platform_id *pPlatformIDs;
    
    			// the number of devices for the first platform
    			cl_uint nb_devices;
    			// the ids of the devices available for the first platform
    			cl_device_id *pDeviceIDs;
    
    			// the OpenCL context
    			cl_context clCtx;
    			// the current cl-program
    			cl_program clProgram;
    			// the loaded kernel within the loaded source
    			cl_kernel clKernel;
    			// the command queue for that kernel
    			cl_command_queue cmdQ;
    
    			void errorHappened(const char* error);
    
    			std::string readKernel(const char* filename);
    
    		public:
    			OpenCLProgram();
    			~OpenCLProgram();
    
    			void loadProgram(const char* filename, const char* kernelName);
    }
    
    #endif /* OPENCLPROGRAM_H_ */
    

    OpenCLProgram.cpp

    #include "openCLProgram.h"
    #include "types.h"
    
    #include <CL/cl.h>
    #include <stdexcept>
    #include <string>
    #include <fstream>
    #include <iostream>
    
    using namespace GRAVID;
    
    OpenCLProgram::OpenCLProgram(){
    	// retrieve platform ids
    	this->pPlatformIDs = NULL;
    	clGetPlatformIDs(NULL,NULL,&(this->nb_platforms));
    	// stop, if there is no OpenCL platform
    	if(0 == this->nb_platforms)
    		this->errorHappened("no OpenCL capable platforms available");
    	this->pPlatformIDs = new cl_platform_id[this->nb_platforms]; // some memory is allocated that has to be freed in the destructor
    	this->errorCode = clGetPlatformIDs(this->nb_platforms,this->pPlatformIDs,NULL);
    	if(CL_SUCCESS != this->errorCode)
    		this->errorHappened("couldn't get the platform ids");
    
    	// obtain the list of GPUs for the first platform
    	this->pDeviceIDs = NULL;
    	clGetDeviceIDs(this->pPlatformIDs[0],CL_DEVICE_TYPE_GPU, NULL, NULL, &this->nb_devices);
    	// stop, if there is no device available
    	if(0 == this->nb_devices)
    			this->errorHappened("no device available for the first platform");
    	this->pDeviceIDs = new cl_device_id[this->nb_devices];
    	this->errorCode = clGetDeviceIDs(this->pPlatformIDs[0],CL_DEVICE_TYPE_GPU, this->nb_devices, this->pDeviceIDs, NULL);
    	if(CL_SUCCESS != this->errorCode)
    			this->errorHappened("couldn't get the device ids");
    
    	// create a context for the devices to use
    	cl_context_properties clContProperties[3];
    	clContProperties[0] = CL_CONTEXT_PLATFORM;
    	clContProperties[1] = (cl_context_properties)this->pPlatformIDs[0];
    	clContProperties[2] = 0;
    	this->clCtx = clCreateContext(clContProperties,this->nb_devices,this->pDeviceIDs,NULL,NULL,&this->errorCode);
    	if(CL_SUCCESS != this->errorCode)
    		this->errorHappened("couldn't create context");
    }
    
    void OpenCLProgram::errorHappened(const char* error){
    	std::string errorMsg = error;
    	throw std::logic_error(errorMsg);
    }
    
    OpenCLProgram::~OpenCLProgram(){
    
    	clReleaseCommandQueue(this->cmdQ);
    
    	clReleaseKernel(this->clKernel);
    
    	clReleaseProgram(this->clProgram);
    
    	clReleaseContext(this->clCtx);
    
    	if(NULL != this->pDeviceIDs)
    			delete(this->pDeviceIDs);
    
    	if(NULL != this->pPlatformIDs)
    		delete(this->pPlatformIDs);
    }
    
    std::string OpenCLProgram::readKernel(const char* filename){
    	std::ifstream inFile;
    	char buffer[256];
    	std::string resultString;
    
    	inFile.open(filename,std::ifstream::in);
    	if(inFile.fail())
    		this->errorHappened("kernel source-file not found");
    
    	while(inFile.good()){
    		inFile.getline(buffer,256);
    		resultString.append(buffer);
    	}
    
    	inFile.close();
    	return resultString;
    }
    
    void OpenCLProgram::loadProgram(const char* filename, const char* kernelName){
    
    	// retrieve the kernel source
    	std::string kernelString = this->readKernel(filename);
    	const char* kernel_cstr = kernelString.c_str();
    	size_t kernelLength = (size_t)kernelString.length();
    	this->clProgram = clCreateProgramWithSource(this->clCtx, 1, &kernel_cstr, &kernelLength,&this->errorCode);
    	if(CL_SUCCESS != this->errorCode)
    		this->errorHappened("couldn't create program from source");
    
    	// build the program
    	// TODO check if there maybe a built version already exists
    	this->errorCode = clBuildProgram(this->clProgram,NULL,NULL,NULL,NULL,NULL);
    	// get Build Information
    	size_t actualSize;
    	clGetProgramBuildInfo(this->clProgram,this->pDeviceIDs[0],CL_PROGRAM_BUILD_LOG,NULL,NULL,&actualSize);
    	char errorMessage[actualSize];
    	clGetProgramBuildInfo(this->clProgram,this->pDeviceIDs[0],CL_PROGRAM_BUILD_LOG,actualSize,(void*)errorMessage,NULL);
    	if(CL_SUCCESS != this->errorCode){
    		std::string totalError = "Building process failed with the following error log:\n";
    		totalError.append(errorMessage);
    		this->errorHappened(totalError.c_str());
    	}
    
    	// extract the kernel within the program
    	this->clKernel = clCreateKernel(this->clProgram,kernelName,&this->errorCode);
    	if(CL_SUCCESS != this->errorCode)
    		this->errorHappened("couldn't extract the specified kernel from the loaded source");
    
    	// creating the commandQueue for the kernel
    	this->cmdQ = clCreateCommandQueue(this->clCtx, this->pDeviceIDs[0], NULL, &this->errorCode);
    	if(CL_SUCCESS != this->errorCode)
    		this->errorHappened("couldn't create command queue");
    }
    

    Sry, but I couldn't post less to make it work (or in this case not work).



  • Achja und sry dafür dass mir manchmal die Srachorientierung fehlt 😉



  • keine angst - das mit der sprachorientierung wird niemanden stören - weil du offenbar nicht fähig bist ein _compilierbares minimalbeispiel_ zu posten...

    bb


Anmelden zum Antworten