malloc函数上的分段故障 [英] Segmentation fault on malloc function
问题描述
我有一个脚本通过 SSH ( libssh2
)连接到我的10台服务器之一。程序使用 fork
作为线程系统。它正在进入服务器,执行命令(如 free -m
或检查CPU USSAGE),并通过 HTTP REQUEST 发送输出另一个服务器。
它工作正常,但不时发送数据回到HTTP服务器。我做了一个小调试与 puts('DEBUG123 ...')
,看看它在哪里崩溃。我这样做,因为我使用 FORK
,我无法看到它在哪里崩溃。
...从代码
puts(DEBUG 6);
sprintf(param,%s%s,param,my_encode(info));
puts(DEBUG 6.5);
getContent(MY_HOST,HOST_IP,param);
puts(DEBUG 7);
...来自fork的代码
my_encode函数的代码,发送到 HTTP SERVER :
char * my_encode(char * bytes_to_encode)
{
puts(S-DEBUG 1);
int in_len = strlen(bytes_to_encode);
puts(S-DEBUG 1.1);
char buf [5200];
char * res =(char *)malloc(3600);
puts(S-DEBUG 1.2);
memset(buf,0,1200);
puts(S-DEBUG 1.3);
memset(res,0,3600);
puts(S-DEBUG 2);
strcpy(buf,base64_encode(bytes_to_encode,in_len));
for(int i = 0; i {
strcat(res,switch_encode(buf [i]))
}
puts(S-DEBUG 3);
return res;
}
这是我得到的输出:
Linux - >用户名密码1.2.3.4 22
调试2
调试3
调试4
调试5
调试6
S-DEBUG 1
S- DEBUG 1.1
S-DEBUG 1.2
S-DEBUG 1.3
S-DEBUG 2
S-DEBUG 3
DEBUG 6.5
DEBUG 7
DEBUG 1
- 成功发送
Linux - >用户名密码1.2.3.4 22
调试2
调试3
调试4
调试5
调试6
S调试1
S- DEBUG 1.1
S-DEBUG 1.2
S-DEBUG 1.3
S-DEBUG 2
S-DEBUG 3
DEBUG 6.5
DEBUG 7
DEBUG 1
- 成功发送
Linux - >用户名密码1.2.3.4 22
调试2
调试3
调试4
调试5
调试6
S-DEBUG 1
S- DEBUG 1.1
S-DEBUG 1.2
S-DEBUG 1.3
S-DEBUG 2
S-DEBUG 3
DEBUG 6.5
DEBUG 7
DEBUG 1
- 成功发送
Linux - >用户名密码1.2.3.4 22
调试2
调试3
调试4
调试5
调试6
S-DEBUG 1
S- DEBUG 1.1 <---这里它正在进行
调试1
- 发送错误
Linux - >用户名密码1.2.3.4 22
调试2
调试3
调试4
调试5
调试6
S-DEBUG 1
S- DEBUG 1.1
S-DEBUG 1.2
S-DEBUG 1.3
S-DEBUG 2
S-DEBUG 3
DEBUG 6.5
DEBUG 7
- 成功发送
Linux - >用户名密码1.2.3.4 22
调试2
调试3
调试4
调试5
调试6
S-DEBUG 1
S- DEBUG 1.1 <---这里正在进行扫描
调试1
- 发送错误
所以,为了我的理解,它是崩溃在 malloc
funtion这里:
char * res =(char *)malloc(3600);
这是我发送的基本消息:
用户名:密码:1.2.3.4:22:Linux:Intel Core 2 TM CPU E8200 @ 2.77GHz:242 238 3 0 15 64:no_server_load]
有时它会崩溃。
我也改变了 char * res =(char *)malloc(3600); ,原来是
)malloc(1200);
。
- 问题在哪里?
- 我需要重写
my_encode
函数,这样它不会再崩溃?解决方案 / div>sprintf(param,%s%s,param,my_encode(info));
是一个错误。
这可能意味着
code>虽然最好包含一个缓冲区大小检查。strcat(param,my_encode(info));
您的代码遇到了没有包括任何防止缓冲区溢出的方法。可能有溢出发生,但你不知道在哪里。这可能或可能不会导致你的问题,你没有办法告诉。即使没有,那么改变输入可能会导致一个。
这是一个糟糕的代码,你的生活将很难调试它。我的建议是重写所有这些代码,以包括严格检查缓冲区大小,并确保你不会读取或写入超过缓冲区的结尾。在C ++中,最简单的方法是使用可调整大小的容器。
I have a script that connects on one of my 10 servers trough SSH (
libssh2
). The program usesfork
as a threading system. It is entering the server, executes a command (likefree -m
or check the CPU USSAGE), and sends the output trough a HTTP REQUEST to another server.It works just fine, but from time to time it is not sending data back to the HTTP SERVER. I done a little debug with
puts('DEBUG123 ...')
to see where it is crashing. I do this because i useFORK
and i am unable to see where it is crasing. Down there you see the code.... code from the fork puts("DEBUG 6"); sprintf(param,"%s%s",param,my_encode(info)); puts("DEBUG 6.5"); getContent(MY_HOST,HOST_IP,param); puts("DEBUG 7"); ... code from the fork
code of the my_encode functions that encrypts my data before sending it to the HTTP SERVER :
char *my_encode(char* bytes_to_encode) { puts("S-DEBUG 1"); int in_len = strlen(bytes_to_encode); puts("S-DEBUG 1.1"); char buf[5200]; char *res = (char *)malloc(3600); puts("S-DEBUG 1.2"); memset(buf,0,1200); puts("S-DEBUG 1.3"); memset(res,0,3600); puts("S-DEBUG 2"); strcpy(buf,base64_encode(bytes_to_encode,in_len)); for(int i=0;i<strlen(buf);i++) { strcat(res,switch_encode(buf[i])); } puts("S-DEBUG 3"); return res; }
This is the output that i am getting :
Linux -> username password 1.2.3.4 22 DEBUG 2 DEBUG 3 DEBUG 4 DEBUG 5 DEBUG 6 S-DEBUG 1 S-DEBUG 1.1 S-DEBUG 1.2 S-DEBUG 1.3 S-DEBUG 2 S-DEBUG 3 DEBUG 6.5 DEBUG 7 DEBUG 1 -- SUCCESSFUL SEND Linux -> username password 1.2.3.4 22 DEBUG 2 DEBUG 3 DEBUG 4 DEBUG 5 DEBUG 6 S-DEBUG 1 S-DEBUG 1.1 S-DEBUG 1.2 S-DEBUG 1.3 S-DEBUG 2 S-DEBUG 3 DEBUG 6.5 DEBUG 7 DEBUG 1 -- SUCCESSFUL SEND Linux -> username password 1.2.3.4 22 DEBUG 2 DEBUG 3 DEBUG 4 DEBUG 5 DEBUG 6 S-DEBUG 1 S-DEBUG 1.1 S-DEBUG 1.2 S-DEBUG 1.3 S-DEBUG 2 S-DEBUG 3 DEBUG 6.5 DEBUG 7 DEBUG 1 -- SUCCESSFUL SEND Linux -> username password 1.2.3.4 22 DEBUG 2 DEBUG 3 DEBUG 4 DEBUG 5 DEBUG 6 S-DEBUG 1 S-DEBUG 1.1 <--- HERE IT IS CRASHING DEBUG 1 -- ERROR ON SEND Linux -> username password 1.2.3.4 22 DEBUG 2 DEBUG 3 DEBUG 4 DEBUG 5 DEBUG 6 S-DEBUG 1 S-DEBUG 1.1 S-DEBUG 1.2 S-DEBUG 1.3 S-DEBUG 2 S-DEBUG 3 DEBUG 6.5 DEBUG 7 -- SUCCESSFUL SEND Linux -> username password 1.2.3.4 22 DEBUG 2 DEBUG 3 DEBUG 4 DEBUG 5 DEBUG 6 S-DEBUG 1 S-DEBUG 1.1 <--- HERE IT IS CRASHING DEBUG 1 -- ERROR ON SEND
So for my understanding, it is crashing at the
malloc
funtion here :char *res = (char *)malloc(3600);
And this is a basic message that i send :
username:password:1.2.3.4:22:Linux:Intel(R) Core(TM)2 Duo CPU E8200 @ 2.77GHz:242 238 3 0 15 64:no_server_load]
Sometimes it is crashing on it.
Also i have changed the line
char *res = (char *)malloc(3600);
, originally it waschar *res = (char *)malloc(1200);
. I believed that i don't have enough memory space.- Where is the problem?
- Do i need to rewrite the
my_encode
function so it will no longer crash? If so, how??
Thanks.
解决方案sprintf(param,"%s%s",param,my_encode(info));
is an error. The input and output cannot overlap for sprintf, this causes undefined behaviour.You probably meant
strcat(param, my_encode(info));
although it would be better to include a buffer size check.Your code suffers from not including any method of preventing buffer overflows. There could be overflows happening but you don't know where. This may or may not be causing your problem, you have no way of telling. Even if there isn't, then changing the input may cause one.
This is a poor way to code and your life will be difficult trying to debug it. My advice would be to rewrite all of this code to include strict checking of buffer sizes and ensure that you never read or write past the end of a buffer. In C++ the easiest way to do this is to use resizeable containers.
这篇关于malloc函数上的分段故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文