malloc函数的分段错误

时间:2016-03-08 17:11:59

标签: c++ pointers

我有一个脚本通过 SSH libssh2)连接我的10台服务器之一。该程序使用fork作为线程系统。它正在进入服务器,执行命令(如free -m或检查CPU USSAGE),并通过 HTTP REQUEST 将输出发送到另一台服务器。

它工作正常,但有时它不会将数据发送回HTTP SERVER。我用puts('DEBUG123 ...')做了一点调试,看看它崩溃的地方。我这样做是因为我使用FORK并且我无法看到它在哪里被删除。在那里,你看到了代码。

... 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

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<strlen(buf);i++)
    {
        strcat(res,switch_encode(buf[i]));
    }
    puts("S-DEBUG 3");
    return res;

}

这是我得到的输出:

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

所以根据我的理解,这里的malloc功能崩溃了:

char *res = (char *)malloc(3600);

这是我发送的基本信息:

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]

有时会崩溃。

此外,我更改了行char *res = (char *)malloc(3600);,原来是char *res = (char *)malloc(1200);。我相信我没有足够的存储空间。

  1. 问题出在哪里?
  2. 我是否需要重写my_encode函数以使其不再崩溃?如果是这样,怎么??
  3. 感谢。

3 个答案:

答案 0 :(得分:1)

你必须做这样的事情(释放你的缓冲区):

#include <string>
void my_encode(char* bytes_to_encode, std::string& encoded) {
    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");

    encoded = res;
    free(res);
}

void main() {
    char *s = new char[32];
    strcpy(s, "hello");
    std::string str;
    my_encode (s, str);
    const char* result = str.c_str();
}

答案 1 :(得分:1)

sprintf(param,"%s%s",param,my_encode(info));是一个错误。 sprintf的输入和输出不能重叠,这会导致未定义的行为。

你可能意味着strcat(param, my_encode(info));虽然最好包含一个缓冲区大小检查。

您的代码不包括任何阻止缓冲区溢出的方法。可能会发生溢出,但你不知道在哪里。这可能会也可能不会导致您的问题,您无从谈论。即使没有,但改变输入可能会导致一个输入。

这是一种糟糕的代码编写方式,您的生活很难尝试调试。我的建议是重写所有这些代码,包括严格检查缓冲区大小,并确保您永远不会读取或写入缓冲区的末尾。在C ++中,最简单的方法是使用可调整大小的容器。

答案 2 :(得分:0)

如果您使用的是C++ - 使用std::string来管理内存并避免分配/解除分配问题。

//get base64.cpp and base64.h 
//from here http://www.adp-gmbh.ch/cpp/common/base64.html
#include <base64.h>

std::string my_encode(const std::string& bytes_to_encode)
{
    puts("S-DEBUG 1");
    std::string output = base64_encode(bytes_to_encode.c_str(),bytes_to_encode.length());
    puts("S-DEBUG 2");
    return output;
}