在使用dlopen()对象时确定调用对象

时间:2011-01-22 11:04:53

标签: c plugins dlopen backtrace

我正在编写一个(C)程序,该程序通过dlopen()使用插件系统。我遇到的绊脚石是主程序导出一些真正需要知道调用它们的插件的函数(主要是记录保存,所以插件可以正常卸载,因为它们添加了像main这样的函数指针程序)。

我似乎找不到干净的方法来做到这一点。到目前为止我提出的选项:

  1. 要求插件提供其名称,或者我在加载时提供的一些数据作为函数的参数
    • 我不喜欢这个选项,因为并非所有的功能都关心他们被调用的人,所以它使它变得不一致和混乱。另外,我想让插件尽可能地让人难以理解它是谁
  2. 使用backtrace()确定上一个函数的对象名称。
    • 这看起来相当丑陋且不便携。
  3. 要求插件放置包含其名称的文件级结构(或其他变量)(让我们将其称为'plugin_info'进行讨论)。然后在加载插件时使用dlsym()来查找变量并按其名称对其进行索引(如在散列中)。然后输入#define宏,插件使用这些宏来调用函数并将宏添加&plugin_info作为参数。
    • 这就是我现在正在使用的,但它看起来像是hackish。对于一个你必须有宏传递'& plugin_info',如果你只是传递'plugin_info'然后它从主程序而不是插件中提取'plugin_info'。通过地址引用它似乎使得它使用正确的编译,并且它不会被重新定位。这让我不喜欢这个选项,因为它似乎是未定义的行为,但它确实有效。当插件开发人员遇到函数调用问题(传递错误的参数类型或诸如此类的东西)时,宏也会让它有点混乱。
  4. 如果有任何其他想法或技巧,我很乐意知道。

1 个答案:

答案 0 :(得分:2)

  1. 您已将插件邀请到您的地址空间,因此它可以撒谎,覆盖属于来电者的内存,或rm -rf ~(如果有的话)。如果这是一个问题,您需要在没有特权的单独进程中对其进行沙箱化。
  2. 确实这非常不便携。
  3. 这通常是正确的想法,但是你已经搞砸了它并使它变得丑陋。将static添加到plugin_info的定义中,您将拥有完美定义的行为,而且没有任何hackery。