我在信号处理程序中调用了一些C ++函数,我的程序被分段错误终止。 当我用gdb检查时,memcpy()函数是我得到SIGSEGV的地方。 我想知道memcpy()是否是一个可重入函数?
答案 0 :(得分:11)
除了最高度嵌入的平台之外,它都是可重入的。你提到SIGSEGV所以我认为它不是其中之一。在这种情况下,最有可能的是memcpy()不是罪魁祸首:这是调用者的错。如果你要求memcpy()复制坏指针(或坏长度)那么它就会出现故障。你可以很容易地做到这一点:
memcpy(NULL, NULL, 123456789);
这会导致一个SIGSEGV,它会告诉你memcpy()导致它。当然,这不是memcpy的错 - 它只是做你告诉它的。你的信号处理程序用奇怪的东西来调用它。对调用者站点的回溯(在gdb或你拥有的任何工具中)应该显示你所称的内容。如果不这样做,只需打印你传递给memcpy的参数。
答案 1 :(得分:2)
有关(非)可重入函数和信号处理程序的相关信息(与GNU C库相关)可以在http://www.gnu.org/s/libc/manual/html_node/Nonreentrancy.html#Nonreentrancy找到:
这部分似乎与您的问题特别相关:
“只是从内存对象中读取是安全的,前提是您可以处理信号交付时可能出现在对象中的任何值。请记住,对某些数据类型的赋值需要多个指令,这意味着如果处理程序的类型不是原子的,那么处理程序可以“在”变量赋值的中间运行。“
“只要在处理程序可能运行的任何时候,值的突然变化都不会打扰任何内容,只是写入内存对象是安全的。”
答案 2 :(得分:1)
我不明白为什么它不可重入。我不确定,但我认为它基于你使用的库很多。
答案 3 :(得分:0)
除非memcpy
实施不当,否则它是可重入的。它只适用于你给它的东西 - 指针和长度值。所有参数都按值传递,因此一旦激活了该函数,无论信号和/或其他线程如何,这些值都不会在其堆栈帧上发生变化。
答案 4 :(得分:0)
我认为问题在于你使用memcpy函数作为无效(或删除)指针的参数,请仔细检查你的代码。
问候。