malloc函数上的分段故障 [英] Segmentation fault on malloc function

查看:160
本文介绍了malloc函数上的分段故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本通过 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);


  1. 问题在哪里?

  2. 我需要重写 my_encode 函数,这样它不会再崩溃?

    解决方案 / div>

    sprintf(param,%s%s,param,my_encode(info)); 是一个错误。



    这可能意味着 strcat(param,my_encode(info));

    code>虽然最好包含一个缓冲区大小检查。



    您的代码遇到了没有包括任何防止缓冲区溢出的方法。可能有溢出发生,但你不知道在哪里。这可能或可能不会导致你的问题,你没有办法告诉。即使没有,那么改变输入可能会导致一个。



    这是一个糟糕的代码,你的生活将很难调试它。我的建议是重写所有这些代码,以包括严格检查缓冲区大小,并确保你不会读取或写入超过缓冲区的结尾。在C ++中,最简单的方法是使用可调整大小的容器。


    I have a script that connects on one of my 10 servers trough SSH (libssh2). The program uses fork as a threading system. It is entering the server, executes a command (like free -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 use FORK 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 was char *res = (char *)malloc(1200);. I believed that i don't have enough memory space.

    1. Where is the problem?
    2. 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屋!

    查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆