2013-10-25 54 views
1

這裏的字符串成員是一個簡單的程序:在gdb爲什麼我不能用printf臨時結構

#include <stdio.h> 
#include <string.h> 

typedef struct { 
     char str[10]; 
} my_struct; 

static my_struct s1; 

int main() 
{ 
     char *temp_str = "test"; 
     strcpy(s1.str, temp_str); 
     printf("%s\n", s1.str); 
} 

這個程序編譯和運行的預期,但我看到用gdb一些奇怪的行爲,我不太明白。這些gdb命令是在printf行上設置的斷點之後運行的。

(gdb) p s1.str 
$5 = "test\000\000\000\000\000" 
(gdb) printf "%s\n", s1.str 
test 
(gdb) set $tmp = s1 
(gdb) printf "%s\n", $tmp.str 
Attempt to take address of value not located in memory. 

爲什麼最後一個命令不起作用?在更復雜的情況下,直接訪問變量(s1.str)不是那麼幹淨,在這個例子中,是否有任何有效的方法在$ tmp之類的地方使用printf?這是與gdb 7.2。

下也不過工作:

(gdb) set $tmp_str = s1.str 
(gdb) printf "%s\n", $tmp_str 
test 

關注的另一點是,如果我一個int的struct(在這種情況下,X - 設置爲4),我可以做成功:

(gdb) set $tmp = s1 
(gdb) printf "%d\n", $tmp.x 
4 
+0

這是值得的,這工作正常gdb-7.6.1。 「printf」%s \ n「,$ tmp.str'和'printf」%s \ n「,$ tmp-> str'輸出」test「 – nos

回答

1

可能是因爲$ TMP指向一個結構(S1),而不是字符數組(s1.str),GDB是非常聰明的事情,但通常要帶的東西字面上。

set $tmp = s1 

一般是指:

set $tmp = (address of)s1 

因此$ TMP只是一個指針,從技術上說,你不得不/要挾$ TMP轉換爲(結構my_struct)類型的指針,從中你可以參考結構內容str。

set $tmp = (struct my_struct)s1 

但我不認爲這會在gdb中工作(不知道肯定,試試吧!)。無論如何:

set $tmp = s1.str 
printf "%s\n", $tmp 

雖然可能會爲你工作。

+0

我在問題中提到過你最後推薦的功能確實有效。另外,將它轉換爲my_struct(不需要類型前面的額外'結構')並沒有幫助。仍然希望得到答案,但如果上面的評論中「nos」是正確的,這可能只是我的gdb版本中的一個bug。 – bgomberg

相關問題