2009-10-30 13 views
2

我有這樣一段代碼在這裏:分段故障在的libpthread鏈接的應用程序捕獲異常時(linux下,C++)

這些是用於創建和停止並行線程功能:

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; 

}; 
+0

它是否有任何區別,如果你通過const引用它呢? – Naveen 2009-10-30 07:26:51

+0

這裏沒有什麼明顯的錯誤。你能在gdb中獲得回溯嗎? – 2009-10-30 07:41:08

+0

在gdb下運行時,它凍結在pthread_join上 - 我認爲它與gdb沒有正確傳遞信號有關 - 我如何配置gdb以將所有信號傳遞給程序? – zbigh 2009-10-30 08:08:06

回答

0

在WatchDogException的構造函數,你記住指針傳入的C-字符串或你在做它的一個副本。

如果您只是存儲指針,那麼當拋出異常時,「err」超出範圍時,c_str()返回的指針將會很糟糕,因此您嘗試使用它時出現seg錯誤。

+0

WatchDogException生成C字符串的內部副本,所以這不是問題。 – 2009-10-30 10:46:05

3

我在猜測你沒有正確地爲retval分配內存,或者你從cn_pr_thread中返回一個無效指針,這就是爲什麼當你調用pthread_join時出現分段錯誤的原因。

+0

我正在傳遞一個未初始化的指針,但我爲該線程內的一個整數分配內存。 你的意思是說可能是什麼意思?函數是否可能超過throw語句? – zbigh 2009-10-30 12:09:07

+0

你可以顯示你爲retval分配內存的位置嗎?至於雙刪除,你是正確的:它不應該超過throw語句。我沒有仔細閱讀。 – 2009-10-30 12:19:40

+0

如果您已經爲線程內返回的數據動態分配內存,則無需擔心,您需要已分配的內容將其複製到內存中。 – 2009-10-30 12:30:11