2012-01-31 18 views
1

我有一個以下函數,我想根據傳遞給它的變量參數的內容停止調試。在可變參數函數中停止斷點

int 
my_fprintf (const char *format, ...) 
{ 
    va_list arg_list; 
    ... 
    va_start (arg_list, format); 
    result = vfprintf (stream, indent_str, arg_list); 
    va_end (arg_list); 

    ... 
    return result; 
} 

我要的是把一個斷點在它停止呼叫是否my_fprintf ("%s", "hello")例如(所以斷點條件是儘可能接近到<smth> == "hello")。

有沒有可能這樣做?

更新:

  • Debugger是GDB。
  • 我知道如何設置條件斷點,我想知道,這種情況應該在這種情況下。
+1

您可能會發現它與您正在使用的調試器的確切位置有關。 – KevenK 2012-01-31 14:38:51

+0

我的調試器是gdb。 – 2012-01-31 15:02:49

回答

1

gdb可以做到這一點。您只需要一個可以檢查的變量(以下片段中的p)。要成功獲得p,您需要更多的goo,即檢查arg2的第一個參數是否屬於char *,這是通過檢查format包含%s來完成的(例如%s不夠,因爲有人可能使用% 。* s或其他)。

static int my_fprintf(const char *format, ...) 
{ 
     const char *p; 
     va_list arg_list, arg2; 
     bool have_string = false; 

     va_start(arg_list, format); 
     va_copy(arg2, arg_list); 
     for (p = strchr(format, '%'); p != NULL; p = strchr(p+1, '%')) { 
       if (p[1] == '%') 
         continue; 
       if (p[1] != 's') 
         break; 
       have_string = true; 
       break; 
     } 
     if (have_string) 
       p = va_arg(arg2, const char *); 
     result = vfprintf(stream, indent_str, arg_list); 
     va_end(arg_list); 
     return result; 
} 

(gdb) b 1234 if have_string && strstr(p, "hello")==0 

用行號p=va_arg...替換1234。
編輯:unshadow p並將have_string放入break cond。

+0

你是在函數頂部宣佈的陰影p) – 2012-01-31 16:10:58

+0

在我看來'if(have_string)...'應該有一個'else {p =「」}'例如用於處理沒有字符串的情況。然後我使用'strcmp'進行嚴格的字符串比較。 除此之外,作品像魅力!謝謝。 – 2012-01-31 16:19:36

0

你將不得不分析你的實現的類型的內臟的va_list類型。例如。它可能是一個指向數組指針的指針,其中一個指針(可能是第一個)指向「hello」。然後教你的調試器打破這種情況。

2

我覺得有兩個部分的提問/回答:

  1. 如何獲得GDB看到可變部分傳遞的參數?我不認爲它有這個能力,所以你必須做一些平臺依賴。 This answer應該適用於x86_64。對於32位,它更簡單,因爲va_list只是一個long數組。
  2. 如何創建條件斷點? gdb的condition命令(記錄here)可以提供幫助。
+0

我的問題實際上是關於第1部分,但謝謝。 – 2012-01-31 15:02:36

+0

所以,如果你在x86_64上,我鏈接的答案應該可以解決它。 – ugoren 2012-01-31 15:08:24

+0

是的,它似乎工作在一般情況下,唯一的問題仍然是斷點條件下的字符串比較 – 2012-01-31 15:22:34