2018年12月4日星期二

不要在名为poll的函数中调用libcurl库,否则进程可能崩溃

最近写的一个程序中,通过调用libcurl库,实现对FTP服务器的上传下载功能。其中一个入口函数叫做poll的线程启动的时候,首先将之前积累的log文件通过libcurl上传到FTP服务器。结果运行的时候,进程直接就挂掉了。通过gdb分析core文件,发现崩溃前的栈如下:
Stack trace of thread 6127:
                #0  0x00007f41d8504e0d __GI___readdir64 (libc.so.6)
                #1  0x000000000040667e update_log_file (bas-ctl)
                #2  0x0000000000406894 poll (bas-ctl)
                #3  0x00007f41d86654c9 n/a (libcurl.so.4)
                #4  0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #5  0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #6  0x00000000004077c0 ftp_upload (bas-ctl)
                #7  0x000000000040670d update_log_file (bas-ctl)
                #8  0x0000000000406894 poll (bas-ctl)
                #9  0x00007f41d86654c9 n/a (libcurl.so.4)
                #10 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #11 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #12 0x00000000004077c0 ftp_upload (bas-ctl)
                #13 0x000000000040670d update_log_file (bas-ctl)
                #14 0x0000000000406894 poll (bas-ctl)
                #15 0x00007f41d86654c9 n/a (libcurl.so.4)
                #16 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #17 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #18 0x00000000004077c0 ftp_upload (bas-ctl)
                #19 0x000000000040670d update_log_file (bas-ctl)
                #20 0x0000000000406894 poll (bas-ctl)
                #21 0x00007f41d86654c9 n/a (libcurl.so.4)
                #22 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #23 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #24 0x00000000004077c0 ftp_upload (bas-ctl)
                #25 0x000000000040670d update_log_file (bas-ctl)
                #26 0x0000000000406894 poll (bas-ctl)
                #27 0x00007f41d86654c9 n/a (libcurl.so.4)
                #28 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #29 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #30 0x00000000004077c0 ftp_upload (bas-ctl)
                #31 0x000000000040670d update_log_file (bas-ctl)
                #32 0x0000000000406894 poll (bas-ctl)
                #33 0x00007f41d86654c9 n/a (libcurl.so.4)
                #34 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #35 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #36 0x00000000004077c0 ftp_upload (bas-ctl)
                #37 0x000000000040670d update_log_file (bas-ctl)
                #38 0x0000000000406894 poll (bas-ctl)
                #39 0x00007f41d86654c9 n/a (libcurl.so.4)
                #40 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #41 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #42 0x00000000004077c0 ftp_upload (bas-ctl)
                #43 0x000000000040670d update_log_file (bas-ctl)
                #44 0x0000000000406894 poll (bas-ctl)
                #45 0x00007f41d86654c9 n/a (libcurl.so.4)
                #46 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #47 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #48 0x00000000004077c0 ftp_upload (bas-ctl)
                #49 0x000000000040670d update_log_file (bas-ctl)
                #50 0x0000000000406894 poll (bas-ctl)
                #51 0x00007f41d86654c9 n/a (libcurl.so.4)
                #52 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #53 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #54 0x00000000004077c0 ftp_upload (bas-ctl)
                #55 0x000000000040670d update_log_file (bas-ctl)
                #56 0x0000000000406894 poll (bas-ctl)
                #57 0x00007f41d86654c9 n/a (libcurl.so.4)
                #58 0x00007f41d865f030 curl_multi_wait (libcurl.so.4)
                #59 0x00007f41d8658433 curl_easy_perform (libcurl.so.4)
                #60 0x00000000004077c0 ftp_upload (bas-ctl)
                #61 0x000000000040670d update_log_file (bas-ctl)
                #62 0x0000000000406894 poll (bas-ctl)
                #63 0x00007f41d86654c9 n/a (libcurl.so.4)

其中bas-ctl中的这几个函数是我写的,看起来发生了循环调用。我在ftp_upload函数中调用了libcurl的函数后,libcurl.so.4中的一个不知名的函数会重新调用我的线程入口poll函数。如此往复循环,直接把栈给干爆了。这种情况我还是第一次遇到。
考虑到我的程序是多线程的,在网上搜了一下多线程使用libcurl要注意的事项,发现大家说的都是那两点(可以网上自己搜,我在这里不赘述). 我把这些注意点在我的程序中改进后,仍然没有解决问题。
后来想libcurl.so.4为什么会重新调用我的poll函数?是不是libcurl中有相同的函数名?于是把poll改为bg_worker, 结果问题解决,函数名也更加见名知意了。

没有评论:

发表评论