Ошибка сегментации при отлове исключений в приложении, связанном с libpthread (linux, C ++) - PullRequest
2 голосов
/ 30 октября 2009

У меня есть этот кусок кода здесь:

Это функции, используемые для создания и остановки pthread:

void WatchdogController::conscious_process_handler_start() {

    if ( debug ) cout << "WatchdogController: starting conscious process thread" << endl;

    cn_pr_thread_active = true;

    if ( pthread_create( &cn_pr_thread, NULL, conscious_process_handler, this ) < 0 ) {
        cn_pr_thread_active = false;
        throw WatchdogException( "Unable to start new thread" );
    }
}

void WatchdogController::conscious_process_handler_stop() {

    if ( debug ) cout << "WatchdogController: stopping conscious process thread" << endl;

    cn_pr_thread_active = false;

    int *retval;

    pthread_join( cn_pr_thread, ( void ** )&retval );

    if ( *retval < 0 ) {
        delete retval;
        string err = string( "Error returned by conscious_process_handler(): " ) + string( pthread_err );
        throw WatchdogException( err.c_str() );
    }

    delete retval;
}

Я использую select () в функции, переданной pthread, и при остановке возвращает ошибку, в результате которой возвращаемое значение из pthread является отрицательным, но это не проблема, я исправлю это позже - проблема в том, что когда исключение здесь брошено:

throw WatchdogException( err.c_str() );

и пойман здесь:

try {
        watchdog_controller->hardware_watchdog_stop();
        watchdog_controller->unconscious_process_handler_stop();
        watchdog_controller->conscious_process_handler_stop();
    }
    catch ( HardwareWatchdogException &e ) {
        cerr << "Error stopping hardware watchdog!" << endl;
        cerr << e.get_reason() << endl;
        string err = string( "Exception thrown by hardware watchdog controller" ) + string( e.get_reason() );
        if ( log ) write_log( err.c_str() );
        delete watchdog_controller;
        return -1;
    }
    catch ( WatchdogException &e ) {
        cerr << "Exception cought when exiting!" << endl;
        cerr << e.get_reason() << endl;
        string err = string( "Exception cought when exiting" ) + string( e.get_reason() );
        if ( log ) write_log( err.c_str() );
        delete watchdog_controller;
        return -1;
    }

Я получаю ошибку сегментации, затем пытаюсь получить доступ к объекту:

cerr << e.get_reason() << endl;

В чем может быть причина?

Ссылка & e указывает на что-то, но кажется, что адрес был недействительным.

Вот класс исключений:

class WatchdogException {

    public:

        /**
            @brief      Default constructor
        */
        WatchdogException() : reason() {
        }

        /**
            @brief      Overloaded constructor - setting the error message
            @param      why         Error message
        */
        WatchdogException( const char *why ) : reason( why ) {
        }

        /**
            @brief      The destructor
        */
        virtual ~WatchdogException() {
        }

        /**
            @brief      A getter for the error message
            @return     Returns a string containing error description
        */
        virtual std::string get_reason() const {
            return reason;
        }

    protected:

        /**
            @var        reason      String containing the error message
        */
        std::string reason;

};

Ответы [ 2 ]

3 голосов
/ 30 октября 2009

Я предполагаю, что вы неправильно распределяете память для retval или что вы каким-то образом возвращаете неверный указатель из cn_pr_thread, и именно поэтому вы получаете ошибку сегментации при вызове pthread_join.

0 голосов
/ 30 октября 2009

В конструкторе WatchDogException вы помните указатель на переданную c-строку или делаете ее копию.

Если вы просто сохраняете указатель, то когда "err" выходит из области видимости, когда выбрасывается исключение, указатель, возвращаемый c_str (), будет плохим, следовательно, ваша ошибка сегмента при попытке его использовать.

...