2011-03-09 44 views
4

在使用Apache Zookeeper C運行時庫調試應用程序時,我在使用GDB中的默認全部停止模式設置斷點時遇到了問題。由於Zookeeper線程無法運行,服務器將超時會話並因此刪除您可能創建的任何臨時znode。使用非停止模式我可以防止發生這種情況,但是我失去了檢查任何非Zookeeper線程狀態的便利。有沒有辦法讓一個應用程序線程在GDB的斷點處繼續運行?

GDB中有一種方法可以指定一個(或多個)線程在命中斷點時將繼續在應用程序中運行,但其他線程將停止運行?這樣我就可以檢查我關心的線程的狀態,並忽略那些我想在後臺運行的狀態。

編輯:這本質上是not stopping all threads in gdb的重複。在那裏使用後臺命令和非停止模式的解決方案基本上解決了我的問題,因爲我可以隨時停止線程並異步重新啓動它們,所以也許我們應該關閉這個線程。

+0

你的意思是... ...,但其他人將被停止«,對吧? – klickverbot

+0

對。這個問題沒有清楚嗎?編輯:固定錯字 – tyree731

回答

0

通過Zookeeper,您可以執行一項攻擊,以便在gdb中中斷會話時繼續進行。這個黑客利用動物園管理員的一些屬性和gdb:

  • 你可以有相同的會話ID多次動物園管理員客戶
  • GDB不會在父母阻止子進程斷點
  • 可以忽略的GDB信號子進程而不影響父進程

基於此,解決方案將生成一個子進程,該進程使用與父進程相同的客戶端ID連接到Zookeeper,並且不執行任何操作。然而,Zookeeper客戶端具有會話移動的概念,每隔一段時間客戶端就會切換與之連接的服務器。如果您有兩個具有相同會話ID的客戶端,則其中一個客戶端可能會將另一個連接到未保持其會話的服務器。爲防止這種情況發生,孩子只能連接父母當前連接的服務器。家長和孩子這樣如下所示:

Parent(zh): 
    host = zookeeper_get_connected_host(zh) 
    client_id = zoo_client_id(zh) 
    if fork == 0 
    exec child host client_id 
    end 

Child(host, client_id): 
    ignore SIGINT 
    zh = zookeeper_init(host, client_id) 
    while(true) 
    sleep 
    end 

我測試了使用libzookeeper_mt-0.3.3,並描述它的作品。當你做這種黑客攻擊可能令人沮喪時,一些不合理現象開始從Zookeeper日誌中噴出。如果你不能忽視的日誌,你可以將其關閉如下:

zoo_set_debug_level((ZooLogLevel)0); 

它在禁用日誌記錄的動物園管理員的無證方式。

+0

我應該指出,這種方法並不完美,並且在幕後似乎有一些醜陋之處。有時Zookeeper的操作會因爲未知的原因而失敗,我懷疑這與會話持續過程竊取會話有關。無論是哪種情況,您可以通過其他方式解決這個問題,在開發過程中爲您的客戶提供大量的超時時間,在生產中暫停時間很短。 – tyree731

0

這有助於:

http://www.delorie.com/gnu/docs/gdb/gdb_25.html

看起來你可以這樣做 「線程應用[爲threadno]打破LINENO」

+0

好吧,'線程應用'似乎很有幫助,但你給的例子會導致一個特定的線程中斷。我需要更多的東西,比如'線程應用[blah] dont_break'。 – tyree731

0

您可以設置特定線程斷點:

(gdb) help break 
Set breakpoint at specified line or function. 
break [LOCATION] [thread THREADNUM] [if CONDITION] 
LOCATION may be a line number, function name, or "*" and an address. 
If a line number is specified, break at start of code for that line. 
If a function is specified, break at start of code for that function. 
If an address is specified, break at that exact address. 
With no LOCATION, uses current execution address of the selected 
stack frame. This is useful for breaking on return to a stack frame. 

THREADNUM is the number from "info threads". 
CONDITION is a boolean expression. 
+1

這只是意味着只有某些線程觸發斷點時調試器纔會中斷 - 如果發生這種情況,所有線程都將停止。 –

相關問題