2017-04-07 50 views
0

使用libmicrohttpd库时,遇到奇怪的错误一个stringconst char *,并调用MHD_create_response_from_buffer从std :: string转换为const char *导致'Syscall参数socketcall.sendto(msg)指向valdrrind中的无法寻址的字节'错误

这会导致网页响应格式不正常,偶尔会显示二进制数据,而且更少见一点,会使浏览器认为它是文件并下载它。

是什么使这个非常奇怪的是,该错误不出来,如果我发送一个定期为const char,像 const char *cstring = "this is a page"; 只有当我从string转换为const char *const char *cstring = page.c_str();

的Valgrind的输出:

==11105== Thread 2: 
==11105== Syscall param socketcall.sendto(msg) points to unaddressable byte(s) 
==11105== at 0x617464B: send (send.c:31) 
==11105== by 0x565986F: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x565737D: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x565DA3C: MHD_run_from_select (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x565DC8A: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x565DDA1: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x876B0A3: start_thread (pthread_create.c:309) 
==11105== by 0x617362C: clone (clone.S:111) 
==11105== Address 0xe499448 is 24 bytes inside a block of size 56 free'd 
==11105== at 0x4C2A360: operator delete(void*) (vg_replace_malloc.c:507) 
==11105== by 0x401CA5: http_connect(void*, MHD_Connection*, char const*, char const*, char const*, char const*, unsigned long*, void**) (in /home/shpoople/projects/http/main) 
==11105== by 0x5656F70: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x5658427: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x565D988: MHD_run_from_select (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x565DC8A: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x565DDA1: ??? (in /usr/lib/x86_64-linux-gnu/libmicrohttpd.so.10.27.0) 
==11105== by 0x876B0A3: start_thread (pthread_create.c:309) 
==11105== by 0x617362C: clone (clone.S:111) 
==11105== 

以及用于发送该数据的功能(在this page发现,仅修改为使用std::string):

static int send_page (struct MHD_Connection *connection, std::string page) { 
    int ret; 
    struct MHD_Response *response; 
    const char* cstring = page.c_str(); 

    response = MHD_create_response_from_buffer (strlen (cstring), (void *) cstring, MHD_RESPMEM_PERSISTENT); 

    if (!response) { 
     return MHD_NO; 
    } 

    ret = MHD_queue_response(connection, MHD_HTTP_OK, response); 
    MHD_destroy_response (response); 

    return ret; 
} 

回答

2

您的参数std::string page是一个局部变量。当这个函数结束时它的内存被释放。

另一方面,功能MHD_run_from_select和相关显然运行在一个单独的线程。当该线程试图访问缓冲区时,std::string page的内存已被释放。

您应该确保缓冲区保持活动状态,或者通过分配不同的方式或通过阻塞主线程直到获得响应。

+0

感谢您的回复。该函数有一个用于复制缓冲存储器的标志'MHD_RESPMEM_MUST_COPY' – Shpoople

0

我似乎已经解决了我自己的问题。对不起问一个不必要的问题。

问题可通过改变从MHD_RESPMEM_PERSISTENTMHD_create_response_from_buffer第三个参数解决了MHD_RESPMEM_MUST_COPY

再次,我们对此深感抱歉。

相关问题