C 通过返回指针访问函数静态结构时出现分段错误
我的结构如下:C 通过返回指针访问函数静态结构时出现分段错误,c,debugging,data-structures,segmentation-fault,shared-libraries,C,Debugging,Data Structures,Segmentation Fault,Shared Libraries,我的结构如下: 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
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):
然后我有一个程序(我们称之为B)和一个动态库(我们称之为C)。B和C都与A.lib链接。在运行时,B通过dlopen()
打开C,然后通过调用dlsym()
获取C函数func()
的地址
上面的代码是C的func()
函数的主体,当到达该函数时,它会产生分段错误。SEGDFAULT仅在运行于gdb
之外时发生
为什么会这样
编辑:将
sys\u config\t config
设置为全局变量没有帮助。静态局部变量和静态全局变量之间没有区别。静态变量是静态的,这意味着,根据函数调用的需要,它不会在当前函数帧内的堆栈上分配,而是在可执行文件的二进制头中定义的内存的一个预先存在的段中分配
这是我百分之百肯定的。问题是,它们到底放在哪一部分,以及它们是否被适当地共享——这是另一个问题。我在模块之间共享全局/静态变量时也遇到过类似的问题,但通常情况下,问题的核心是非常具体的设置
请考虑到,代码示例很小,而且我很久以前就在那个平台上工作过。我上面写的东西可能会被误用,甚至在某些方面是明显错误的
我认为,重要的是,当你接触到这条线时,你会得到C中的SEGFULT。如果目标地址有效且未写保护,则将整型字段设置为常量不会失败,也不会失败。剩下两种选择:
-函数sys\u get\u config()已崩溃
-或者它返回了一个无效指针
既然您说segfault是在这里提出的,而不是在sys_get_config中提出的,那么唯一剩下的就是后一点:断开的指针
在sys_get_config中添加一些简单的printf,它将转储要返回的地址,然后在调用函数“func”中执行相同的操作。检查它是否为null,并检查sys_get_config中的值是否与返回后的值相同,以确保调用约定正确,等等。进行双重/三重检查的一个好方法是在模块“A”中添加函数sys_get_config的副本(当然名称不同),并检查从sys\u get\u config返回的地址与其副本是否相同。如果不是,链接过程中出现了一些非常错误的情况
模块加载延迟的可能性也很小,您试图引用尚未完全初始化的模块内存。。我很久以前就在linux上工作过,但我记得dlopen有各种加载选项。但是您写道,您通过dlsym获得了地址,因此我认为模块已经加载,因为您已经获得了符号的最终地址。解决方案很简单。不知何故,由于报头不匹配,PATH_MAX常量在B和C的编译单元中的定义不同。我以后需要更加小心。(脸掌)
sys_config_t* sys_get_config(void)
{
static sys_config_t config;
return &config;
}
void func(void)
{
sys_get_config()->connect_delay = 1000;
}