启用libwget的Cookies功能触发段错误问题排查
环境与代码
Debian 12系统,已安装wget2-dev包(自动依赖libwget0),参考官方示例编写的基础HTTP请求代码如下:
#include <stdio.h> #include <stdlib.h> #include <wget.h> int main(int argc, char *argv[]) { wget_http_connection_t *conn = NULL; wget_http_response_t *resp; // 初始化libwget全局配置 wget_global_init( WGET_COOKIES_ENABLED, 1, WGET_COOKIE_SUFFIXES, "public_suffixes.txt", WGET_COOKIE_FILE, "cookies.txt", WGET_COOKIE_KEEPSESSIONCOOKIES, 1, 0); // 执行HTTP GET请求并返回响应 resp = wget_http_get( WGET_HTTP_URL, "http://example.com", WGET_HTTP_MAX_REDIRECTIONS, 5, WGET_HTTP_CONNECTION_PTR, &conn, 0); if (resp) { printf("%s", resp->body->data); // 释放响应资源 wget_http_free_response(&resp); } // 关闭仍在打开的连接 wget_http_close(&conn); // 释放全局资源(valgrind测试需要) wget_global_deinit(); return EXIT_SUCCESS; }
问题现象
当调用wget_global_init时将WGET_COOKIES_ENABLED设为1,程序触发Segmentation Fault。
编辑1:GDB调试输出
执行gdb ./MyApp调试得到:
(gdb) run Starting program: MyApp [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Program received signal SIGSEGV, Segmentation fault. ___pthread_mutex_lock (mutex=0x0) at ./nptl/pthread_mutex_lock.c:80 80 ./nptl/pthread_mutex_lock.c: No such file or directory.
该错误表明程序尝试对**空指针(0x0)**的互斥锁执行lock操作,说明libwget的Cookie模块内部的互斥锁未完成初始化。
编辑2:Valgrind检测结果
执行valgrind --leak-check=full ./MyApp得到:
==42170== Invalid read of size 4 ==42170== at 0x49541C0: pthread_mutex_lock@@GLIBC_2.2.5 (pthread_mutex_lock.c:80) ==42170== by 0x487A7EC: wget_cookie_create_request_header (in /usr/lib/libwget.so.0.0.0) ==42170== by 0x4895153: wget_http_get (in /usr/lib/libwget.so.0.0.0) ==42170== by 0x1091EE: main (main.c:23) ==42170== Address 0x10 is not stack'd, malloc'd or (recently) free'd ==42170== ==42170== ==42170== Process terminating with default action of signal 11 (SIGSEGV) ==42170== Access not within mapped region at address 0x10 ==42170== at 0x49541C0: pthread_mutex_lock@@GLIBC_2.2.5 (pthread_mutex_lock.c:80) ==42170== by 0x487A7EC: wget_cookie_create_request_header (in /usr/lib/libwget.so.0.0.0) ==42170== by 0x4895153: wget_http_get (in /usr/lib/libwget.so.0.0.0) ==42170== by 0x1091EE: main (main.c:23)
错误路径显示,wget_cookie_create_request_header函数中访问了无效内存地址,说明Cookie相关的全局上下文未正确初始化。
编辑3-4:添加-lpthread后问题依旧
在Eclipse CDT构建设置中添加-lpthread(编译和链接阶段均配置),但问题未解决:
Invoking: GCC C Compiler gcc -lpthread -I/usr/include -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/main.d" -MT"src/main.o" -o "src/main.o" "../src/main.c" Invoking: GCC C Linker gcc -lpthread -L/usr/lib -o "MyApp" ./src/main.o -lwget
问题原因与解决方法
该问题并非libwget的bug,而是使用方式不当:启用Cookie功能时,仅通过wget_global_init设置配置项不足以完成Cookie模块的完整初始化,需显式初始化Cookie存储结构,同时确保依赖文件路径正确。
关键修复步骤
- 显式初始化Cookie存储:
在wget_global_init之后,调用wget_cookie_store_init创建Cookie存储实例,确保Cookie模块的内部结构(包括互斥锁)被正确初始化。 - 修正文件路径:
public_suffixes.txt默认位于/usr/share/libwget/,若使用相对路径可能导致文件找不到,可设置为NULL使用默认路径。 - 正确关联Cookie存储到请求:
在wget_http_get中通过参数传入Cookie存储实例,确保请求使用该存储处理Cookie。
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <wget.h> int main(int argc, char *argv[]) { wget_http_connection_t *conn = NULL; wget_http_response_t *resp; wget_cookie_store_t *cookie_store = NULL; // 初始化libwget全局配置 wget_global_init( WGET_COOKIES_ENABLED, 1, WGET_COOKIE_SUFFIXES, NULL, // 使用默认的public_suffixes.txt路径 WGET_COOKIE_FILE, "cookies.txt", WGET_COOKIE_KEEPSESSIONCOOKIES, 1, 0); // 显式初始化Cookie存储 cookie_store = wget_cookie_store_init( WGET_COOKIE_STORE_FILE, "cookies.txt", WGET_COOKIE_STORE_SUFFIX_FILE, NULL, WGET_COOKIE_STORE_KEEP_SESSION_COOKIES, 1, 0); if (!cookie_store) { fprintf(stderr, "Failed to initialize cookie store\n"); wget_global_deinit(); return EXIT_FAILURE; } // 发起HTTP GET请求,关联Cookie存储 resp = wget_http_get( WGET_HTTP_URL, "http://example.com", WGET_HTTP_MAX_REDIRECTIONS, 5, WGET_HTTP_CONNECTION_PTR, &conn, WGET_HTTP_COOKIE_STORE, cookie_store, 0); if (resp) { printf("%s", resp->body->data); wget_http_free_response(&resp); } // 释放资源 wget_http_close(&conn); wget_cookie_store_deinit(&cookie_store); wget_global_deinit(); return EXIT_SUCCESS; }
编译链接优化
使用pkg-config获取libwget的正确编译链接参数,避免手动指定库的顺序错误:
gcc -g -Wall main.c -o MyApp $(pkg-config --libs libwget)
pkg-config会自动包含libwget所需的所有依赖(包括pthread),确保链接顺序正确。
总结
通过显式初始化Cookie存储结构、修正配置文件路径,并使用正确的编译链接方式,即可解决启用Cookie时的段错误问题。
内容的提问来源于stack exchange,提问作者ukll
相关产品推荐
相关产品推荐

