2011-10-19 58 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