在 libpthread 链接应用程序中捕获异常时出现分段错误(linux、C++)

发布于 2024-08-08 23:38:16 字数 3212 浏览 3 评论 0原文

我这里有这段代码:

这些是用于创建和停止 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;
}

我在传递给 pthread 的函数中使用 select() ,当停止时它返回一个错误,导致 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;

};

I have this piece of code here:

These are functions used to create and stop a 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;
}

I use select() in function passed to pthread, and when stopped it returns an error resulting in return value from pthread being negative, but that's not the issue, I'll fix it later - problem is, that when the exception is thrown here:

throw WatchdogException( err.c_str() );

and caught here:

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;
    }

I get segmentation fault then trying to access the object at this point:

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

What could be the reason?

Reference &e points to something, but it seems as if the address was invalid.

Here's the exception class:

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;

};

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡水深流 2024-08-15 23:38:16

我猜测您没有为 retval 正确分配内存,或者不知何故从 cn_pr_thread 返回无效指针,这就是为什么在调用 pthread_join 时出现分段错误代码>.

I am guessing that you are not properly allocating memory for retval, or that somehow you are returning an invalid pointer from cn_pr_thread, and that is why you get a segmentation fault when you call pthread_join.

一口甜 2024-08-15 23:38:16

在 WatchDogException 的构造函数中,您是否还记得指向传入的 c 字符串的指针,或者您是否复制了它。

如果您只是存储指针,那么当抛出异常时“err”超出范围时,c_str() 返回的指针将是错误的,因此当您尝试使用它时会出现段错误。

In WatchDogException's constructor, are you remembering the pointer to the c-string passed in or are you making a copy of it.

If you're simply storing the pointer then when "err" goes out of scope when the exception is thrown the pointer returned by c_str() will be bad, hence your seg fault when you try and use it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文