【发布时间】:2015-01-25 09:24:48
【问题描述】:
在 Ubuntu 14.04 中,我有一个 C++ API 作为共享库,我使用 dlopen 打开它,然后使用 dlsym 创建指向函数的指针。这些函数之一CloseAPI 从内存中释放 API。语法如下:
void* APIhandle = dlopen("Kinova.API.USBCommandLayerUbuntu.so", RTLD_NOW|RTLD_GLOBAL);
int (*CloseAPI) = (int (*)()) dlsym(APIhandle,"CloseAPI");
如果我确保在我的代码中,总是在main 函数返回之前调用CloseAPI 函数,那么一切似乎都很好,我可以在下次再次运行该程序。但是,如果我 Ctrl-C 并在程序有时间调用 CloseAPI 之前中断程序,那么在我下次运行程序时,每当我调用任何 API 函数时都会收到返回错误。我没有文档说明这个错误是什么,但我的直觉是,从程序的上次运行开始,库上有某种锁定。唯一能让我再次运行该程序的方法是重新启动我的机器。无法登录和退出。
所以,我的问题是:
1) 如果我的库是共享库,为什么我认为共享库可以由多个程序同时加载时会出现此错误?
2) 如果我预计Ctrl-C 会经常发生,而无法致电CloseAPI,我该如何解决这个问题?
【问题讨论】:
-
这不是一个真正的解决方案,但是,处理 C-c 的信号处理程序怎么样(和类似的。SIGINT,是吗?)?
-
正如@keyser 所说,通过
signal(2)或sigaction(2)进行信号处理并在处理程序中调用CloseAPI将是可行的方法。 -
已尝试使用 ltrace。此工具显示用户态应用程序对共享库的调用。它通过连接到动态加载系统来实现这一点,允许它插入 shims,显示应用程序在调用时使用的参数,以及库调用报告的返回值。 ltrace 还可以跟踪 Linux 系统调用。
-
您的共享对象 (Kinova.XXX) 似乎制作不正确。主应用程序应该在退出时释放任何共享对象。工具 ltrace 将揭示发生了什么