2011-10-19 198 views
3

我試過使用GDB和Valgrind,但我似乎無法找出問題所在。 有趣的是,程序在正常執行和GDB期間崩潰,但不是Valgrid。malloc內存損壞,打開

爲了幫助您跟隨代碼,繼承人程序的基本點: 通過套接字和UDP與服務器通信傳輸文件,並處理一些基本的數據包丟失。

我不會共享服務器的代碼,因爲我知道問題不在那裏。 可能會讓一些人感到困惑的一點是,我正在使用數字生成器自己實現數據包丟失。現在它並沒有做任何事情,除了讓程序使用另一個recvfrom。

爲了引導您完成程序輸出,客戶端會告訴服務器它想要什麼文件,服務器會告訴客戶端文件將發送多大,然後以塊(一次10個字符)。

輸出顯示發送了哪些塊,接收了多少個字符以及連接字符串是什麼。

從我所知道的文件傳輸成功,它只是我用來寫收到的文件,給我麻煩的打字電話。不知道這是否與我的malloc調用或不。

這裏是源代碼:

pastebin.com/Z79hvw6L

下面是從CLI執行的輸出,和(似乎GDB不提供任何更多信息)Valgrind的:

注意CLI給出了一個malloc內存損壞錯誤,Valgrind沒有。

CLI:http://pastebin.com/qdTKMCD2

的valgrind:http://pastebin.com/8inRygnU

感謝您的幫助!

增加了GDB回溯導致

======= Backtrace: ========= 
/lib/i386-linux-gnu/libc.so.6(+0x6b961)[0x19a961] 
/lib/i386-linux-gnu/libc.so.6(+0x6e15d)[0x19d15d] 
/lib/i386-linux-gnu/libc.so.6(__libc_malloc+0x63)[0x19ef53] 
/lib/i386-linux-gnu/libc.so.6(+0x5c2b8)[0x18b2b8] 
/lib/i386-linux-gnu/libc.so.6(fopen+0x2c)[0x18b38c] 
/home/---/client[0x8048dc2] 
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x145e37] 
/home/---/client[0x8048871] 

也許這可以給別人的洞察力,以什麼部分程序的錯誤是嗎?

+3

一般而言,如果您無法在帖子的上下文中發佈相關來源子集,則不會收到很多回復。 – Joe

+0

你爲什麼不在valgrind的崩潰位置發佈回溯?我敢打賭,如果你得到了回溯,那麼在損壞的內存(崩潰點)上設置一個內存觀察點會引發你的問題。 – dbeer

+0

你是什麼意思喬?我認爲問題出在哪裏? – user974703

回答

3
char chunk[10]; 
chunk[10] = '\0'; 

是錯誤的,chunk [10]是數組中的一個。

而在一般情況下,要小心如果你輸入一個長文件名這樣

char filename[25]; 
scanf("%s",filename); 

,你將垃圾內存。使用fgets()會更好。您還至少要檢查scanf是否成功,否則以下strlen()文件名無效。

line 93,buf[strlen(buf)-1]='\0';是危險的,如果緩衝區還沒有被終止,那麼你不能使用strlen,並且如果buf是一個空字符串,就像你索引buf [-1]一樣垃圾內存。

編輯。 您的其他問題是strcat(fullstring,chunk);,如果您碰巧接收到的數據超過了可以容納的數據,那麼您的循環中無法控制附加到此字符串的附加信息。大小也可能是1,因爲你需要最後nul終結者的空間。至少讓它成爲char * fullstring = malloc(sizeof(char)*filesize + 1);但是你的循環真的需要檢查它是不是寫過該緩衝區的末尾。

與添加NUL終止符buf的recv調用返回你多少字節讀取,因此,如果您已經檢查recv的錯誤,做buf[numbytes] = 0,但這將是關閉由一個爲好,因爲你已經爲buf分配了10個字節,並且您還嘗試讀入10個字節 - 但是在C中,字符串還需要空間以用於nul終止符。使buf 11個字節大。或者recv()只有9個字節。

事實上,你離開了很多地方,所以開始計算你需要多少字節,並且你把東西放進去了。請記住,在C,數組始於索引爲零,和10的陣列可以僅通過索引0被索引到9

+0

改變了塊[10]位,但沒有結果。我按照原樣離開文件名,一旦我有事情的工作,然後我會做錯誤檢查。 如果我知道buf不會被空終止,我怎麼能添加一個空終止符到它沒有strlen? – user974703

+0

謝謝,答案是我走出了整個字符串和大塊的界限。我必須像你所建議的那樣增加全部字符串,並且正確地終止每個塊。 我會研究解決其他問題。 – user974703

1

那麼,它不應該是現代操作系統上的問題:es,但是你不檢查從malloc()返回NULL的值。在哪條線路上發生了什麼信號?

+0

它在fopen上崩潰,我怎麼知道它崩潰的信號?它說馬洛克 - 記憶腐敗,如果這就是你的意思。 – user974703

2

這(線93)是可疑的:

buf[strlen(buf)-1]='\0'; 

更新這(線99100 )也是錯誤的:

char chunk[10]; 
chunk[10] = '\0'; 

UPDATE2:緩衝區太小

char * fullstring = malloc(sizeof(char)*filesize); // line 103 
... 
strcat(fullstring,chunk); // line 124 

UPDATE3: UDP不可靠。數據包的傳輸可能會失敗(數據包可能在發送者和接收者之間的任何地方丟失),並且數據包的接收順序可能與您發送數據包的順序不同。

+0

糟糕,有人(nos)已經看到了它。 – wildplasser