【问题标题】:Segmentation fault while accessing a function-static structure via returned pointer通过返回的指针访问函数静态结构时出现分段错误
【发布时间】:2011-11-15 11:46:55
【问题描述】:

我有以下结构:

struct sys_config_s
{
  char server_addr[256];
  char listen_port[100];
  char server_port[100];
  char logfile[PATH_MAX];
  char pidfile[PATH_MAX];
  char libfile[PATH_MAX];
  int  debug_flag;
  unsigned long connect_delay;
};
typedef struct sys_config_s sys_config_t;

我还在静态库中定义了一个函数(我们称之为 A.lib):

sys_config_t* sys_get_config(void)
{
  static sys_config_t config;
  return &config;
}

然后我有一个程序(我们称之为 B)和一个动态库(我们称之为 C)。 B 和 C 都与 A.lib 链接。在运行时,B 通过dlopen() 打开C,然后通过调用dlsym() 获得C 的函数func() 的地址。

void func(void)
{
  sys_get_config()->connect_delay = 1000;
}

上面的代码是 C 的 func() 函数的主体,到达时会产生分段错误。段错误仅在gdb 之外运行时发生。

为什么会这样?

编辑:将 sys_config_t config 设为全局变量并没有帮助。

【问题讨论】:

    标签: c debugging data-structures segmentation-fault shared-libraries


    【解决方案1】:

    变量是静态局部变量还是静态全局变量没有区别。静态变量是 STATIC,这意味着它不是在函数调用请求时分配在当前函数帧内的堆栈上,而是分配在可执行文件的二进制标头中定义的内存的预先存在的段之一中。

    这是我 100% 确定的。问题是,它们究竟放在了哪个部分,以及它们是否被正确共享——是另一个问题。我已经看到在模块之间共享全局/静态变量的类似问题,但通常,问题的核心非常具体到确切的设置..

    请注意,代码示例很小,我很久以前就在那个平台上工作过。我在上面写的内容可能在某些时候措辞有误,甚至明显是错误的!

    我认为,重要的是当你接触那条线时,你在 C 中遇到了段错误。将整数字段设置为常量不会失败,也不会失败,前提是目标地址有效且没有写保护。这留下了两个选择: - 您的函数 sys_get_config() 已崩溃 - 或者它返回了一个无效的指针。

    既然你说这里提出了segfault,而不是在sys_get_config中,那么唯一剩下的就是后一点:损坏的指针。

    在 sys_get_config 中添加一些简单的 printf,它将转储要返回的地址,然后在调用函数“func”中执行相同的操作。检查它是否不为空,并检查在 sys_get_config 中它是否与返回后相同,以确保调用约定是正确的,等等。进行双重/三重检查的一个好主意是在模块 "A" 函数 sys_get_config 的副本(当然名称不同),并检查从 sys_get_config 返回的地址和它的副本是否相同。如果不是 - 链接过程中出了点问题

    模块加载延迟的可能性也非常小,并且您正在尝试引用尚未完全初始化的模块的内存..我很久以前在linux上工作过,但我记得dlopen 有各种加载选项。但是您写道,您通过 dlsym 获得了地址,所以我想模块已经加载,因为您已经获得了符号的最终地址..

    【讨论】:

      【解决方案2】:

      解决方案很简单。不知何故,由于头文件不匹配,PATH_MAX 常量在 B 和 C 的编译单元中定义不同。我以后需要更加小心。 (捂脸

      【讨论】:

        猜你喜欢
        • 2020-02-09
        • 2017-02-08
        • 1970-01-01
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-23
        相关资源
        最近更新 更多