在 libpthread 链接应用程序中捕获异常时出现分段错误(linux、C++)
我这里有这段代码:
这些是用于创建和停止 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我猜测您没有为
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 callpthread_join
.在 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.