5

我在信号处理程序中调用了一些 C++ 函数,我的程序因分段错误而终止。当我检查 gdb 时,memcpy() 函数是我获得 SIGSEGV 的地方。我想知道 memcpy() 是否是可重入函数?

4

5 回答 5

11

在除高度嵌入式平台之外的所有平台中,它将是可重入的。您提到了 SIGSEGV,所以我认为它不是其中之一。在这种情况下,很可能 memcpy() 不是罪魁祸首:这是调用者的错。如果您要求 memcpy() 复制错误的指针(或错误的长度),那么它将是出错的那个。你可以很容易地做到这一点:

memcpy(NULL, NULL, 123456789);

这会导致一个 SIGSEGV 并且它会告诉你 memcpy() 导致了它。当然,这不是 memcpy 的错——它只是按照你说的去做。您的信号处理程序以奇怪的方式调用它。对调用者站点的回溯(在 gdb 或您拥有的任何工具中)应该显示您调用它的内容。如果做不到这一点,只需 printf 传递给 memcpy 的参数。

于 2011-03-17T08:17:35.770 回答
2

可以在http://www.gnu.org/s/libc/manual/html_node/Nonreentrancy.html#Nonreentrancy找到有关(非)可重入函数和信号处理程序(与 GNU C 库相关)的一些相关信息:

这部分似乎与您的问题特别相关:

  • “仅仅从内存对象中读取是安全的,前提是您可以处理在可以传递信号时可能出现在对象中的任何值。请记住,分配给某些数据类型需要不止一条指令,这意味着如果变量的类型不是原子的,则处理程序可以在对变量的赋值“中间”运行。”

  • “只要值的突然变化,在处理程序可能运行的任何时候,不会干扰任何东西,仅仅写入内存对象是安全的。”

于 2011-03-17T08:29:37.177 回答
1

我不明白为什么它不能重入。我不确定,但我认为这很大程度上取决于您使用的库。

于 2011-03-17T08:16:00.947 回答
0

我认为问题在于您将无效(或已删除)指针用作 memcpy 函数的参数,请仔细检查您的代码。

问候。

于 2011-03-17T09:01:05.773 回答
0

除非memcpy实施不当,否则它是可重入的。它只适用于你给它的东西——指针和长度值。所有参数都是按值传递的,因此一旦函数被激活,这些值将不会在其堆栈帧上更改,无论信号和/或其他线程如何。

于 2011-03-17T08:37:20.567 回答