我正在使用Linux系统上的setcontext()
,makecontext()
,getcontext()
和swapcontext()
在C ++中实现用户级线程库。
我使用包装函数来包装用户想要作为线程运行的函数。例如,用户调用newthread(funcPtr)
,并在线程库funcPtr
内传递给运行它的包装函数。
根据我是否在函数中启动未使用的字符串,错误会有所不同。如果我包含行string s = "a";
,程序将运行完成,但gdb
显示上下文正在切换到字符串库中的某个位置。如果没有这一行,程序会在离开函数包装器后发生段错误。
gdb
输出显示参数损坏为function()
。
我运行了valgrind
,但在输出中没有看到任何特别不寻常的东西,只有很多“无效读取大小4”和“无效写入大小4”警告,通常是在C ++标准{{ 1}}。
答案 0 :(得分:3)
您也可以尝试AddressSanitizer进行调试。它可以检测堆栈缓冲区溢出。以下是如何在Linux上使用它:
AddressSanitizer至少需要gcc 4.8,必须安装libasan(例如以root身份安装在Fedora yum install libasan
上)。编译并链接-g -fsanitize=address
并运行生成的可执行文件。如果AddressSanitizer检测到第一个错误,则不会停止并发出信息,不需要分析长日志文件。解决报告的问题,再次编译并运行,直到AddressSanitizer不再停止程序。不幸的是,由于您在程序中使用了swapcontext,因此可能存在误报,但值得一试。通过添加属性no_sanitize_address可以关闭特定功能的检测:extern int func(void) __attribute__((no_sanitize_address));