Question

I'm writing a (C) program which utilizes a plugin system via dlopen(). The stumbling block I'm running across is that the main program exports a few functions which really need to know the plugin that called them (mostly record keeping, and so a plugin can be unloaded properly as they add things like function pointers to the main program).

I cant seem to find a clean way to do this. The options I've come up with so far:

  1. require the plugin to provide its name, or some data I give it on load as an argument to the functions.
    • I dont like this option because not all functions care who they were called from, so it makes it inconsistent and messy. Plus I would like to make it as difficult as possible for the plugin to lie about who it is
  2. Use backtrace() to determine the object name of the previous function.
    • This just seems fairly ugly and non-portable.
  3. Require the plugin to put a file-level struct (or other variable) containing its name (lets call it 'plugin_info' for discussion). Then use dlsym() when loading the plugin to look up the variable and index it (like in a hash) by its name. Then put in #define macros which the plugins use to call the functions and have the macro add &plugin_info as an argument.
    • This is what I'm using now but it seems hackish. For one you have to have the macro pass '&plugin_info', if you just pass 'plugin_info' then it pulls the 'plugin_info' from the main program, not the plugin. Referencing it by address seems to make it so that its compiled with the correct one, and that it doesnt get relocated. That makes me dislike this option as that seems like its undefined behavior, however it does work. Also the macros can make it a bit confusing when the plugin developer has a problem with the function call (passing wrong argument type or whatnot).

If there's any other ideas or techniques, I would love to love to know.

Was it helpful?

Solution

  1. You've invited the plugin into your address space, so it can lie, overwrite memory belonging to the caller, or rm -rf ~ if it likes. If this is a problem, you need to sandbox it in a separate process without privileges.
  2. Indeed this is horribly non-portable.
  3. This is generally the right idea, but you've botched it and made it ugly. Add static to plugin_info's definition and you'll have perfectly well-defined behavior and none of the hackery.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top