exporting symbols from executable

737 views
Skip to first unread message

Zori Kostadinova

unread,
Jun 18, 2012, 9:31:42 PM6/18/12
to chromium-dev
Hello,

Does anyone know of drawbacks (performance penalties) to exporting
symbols from executables? The way I did that (on linux) was passing
the -rdynamic flag to the linker. Without the flag the symbols are not
found. Example attached.

In particular, I'd like to export from chrome and content_shell to
make symbols available to a dynamically loaded testing module.

Zori
exporting_symbols.tar.gz

William Chan (陈智昌)

unread,
Jun 19, 2012, 2:35:18 PM6/19/12
to zo...@chromium.org, chromium-dev, Ricardo Vargas, Jói Sigurðsson, Jeffrey Yasskin
[ Adding random folk who probably know more than me here. +rvargas, +joi, +jyasskin and can correct any misinformation ]

If you want to ship code to actual users with something like -rdynamic that exports *all* symbols, then that's probably a no-go. I think there are two main things to watch out for here: binary bloat and startup time regression. I don't have a good sense for the *actual* costs here, but for your kind of change, we actually have reasonable performance tests that will catch any noticeable regression, so you can test it out. Binary bloat is possible because you are exporting symbols that previously were known to be unused, and therefore stripped. If they're being exported, then it becomes possible for them to get called, so it may prevent them from getting stripped from the binary. Startup time regression is possible because of increased work on the part of the dynamic loader due to the extra symbols.

If you only want to ship specific symbols, like we do in the automation interface, then that's fine. I believe this is what we do for ChromeFrame.


Zori

--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
   http://groups.google.com/a/chromium.org/group/chromium-dev

Ken Kania

unread,
Jun 19, 2012, 3:53:18 PM6/19/12
to will...@chromium.org, zo...@chromium.org, chromium-dev, Ricardo Vargas, Jói Sigurðsson, Jeffrey Yasskin
Thanks for the comment.  To give a little background, Zori is trying to enable chrome to load a DLL which can speak to chrome using a private automation interface.  For the interface, Zori is trying to decide between:

1) Exporting symbols from the executable and linking appropriately when building the automation DLL
class AUTO_EXPORT Tab {
  void LoadUrl(const std::string& url);
};
On mac, when building chrome we'd need to do something like -Wl,-exported_symbols_list, <file containing automation symbols>.  When building the shared object we'd need to use -bundle_loader.

On linux, I'm not sure how we could restrict chrome to just exporting a few symbols and not all of them through rdynamic.  Maybe we could strip everything out we don't need?  When building the shared object we shouldn't have to do anything since gcc won't complain about undefined symbols.

On windows, I think it should just work.


2) Don't do any exporting, just rely on the vtable and pass in a function pointer to instantiate an object (or something similar)
//  In the module:
void AUTO_EXPORT Init(Tab* (*create_tab_func)()) {
  create_tab_func()->LoadUrl("www.google.com");
}

// In shared header:
class Tab {
  virtual void LoadUrl(const std::string& url) = 0;
};


Exporting symbols from Chrome sounds a bit hairy to me, but we wanted to get input from someone with expertise before deciding.

Ken

Jói Sigurðsson

unread,
Jun 19, 2012, 4:14:36 PM6/19/12
to Ken Kania, will...@chromium.org, zo...@chromium.org, chromium-dev, Ricardo Vargas, Jeffrey Yasskin
Personally, I would explicitly export one or a few functions, and pass
pointers to pure virtual interfaces out of those functions. Each
interface can be more than just one function. This is a proven
approach (e.g. used in Microsoft COM) and probably the easiest to make
consistent across platforms, without any of the risks that Will
mentioned.

Are there significant drawbacks to that approach as opposed to
exporting all of the symbols you need individually?

Cheers,
Jói

Ken Kania

unread,
Jun 19, 2012, 4:37:19 PM6/19/12
to Jói Sigurðsson, will...@chromium.org, zo...@chromium.org, chromium-dev, Ricardo Vargas, Jeffrey Yasskin
There's no significant drawbacks I can think of with using the pure virtual interfaces.  Approach #2 (ie, passing a pointer to the factory function to the DLL's Init func) sounds easier to me.  I'd prefer not to have to deal with any of the platform-specific linking stuff.

You mentioned exporting a few factory functions from Chrome.  Is there a reason to choose that instead?

Ken

Jói Sigurðsson

unread,
Jun 19, 2012, 4:39:40 PM6/19/12
to Ken Kania, will...@chromium.org, zo...@chromium.org, chromium-dev, Ricardo Vargas, Jeffrey Yasskin
> You mentioned exporting a few factory functions from Chrome.  Is there a
> reason to choose that instead?

I was just thinking about it the wrong way. Simplest to export a
factory from the DLL as you said. Whether you have a single factory
or a few depends on whether you want a single root object or a few.
I'm guessing one is fine.

Antoine Labour

unread,
Jun 19, 2012, 5:03:41 PM6/19/12
to will...@chromium.org, zo...@chromium.org, chromium-dev, Ricardo Vargas, Jói Sigurðsson, Jeffrey Yasskin
On Tue, Jun 19, 2012 at 11:35 AM, William Chan (陈智昌) <will...@chromium.org> wrote:
[ Adding random folk who probably know more than me here. +rvargas, +joi, +jyasskin and can correct any misinformation ]

If you want to ship code to actual users with something like -rdynamic that exports *all* symbols, then that's probably a no-go. I think there are two main things to watch out for here: binary bloat and startup time regression. I don't have a good sense for the *actual* costs here, but for your kind of change, we actually have reasonable performance tests that will catch any noticeable regression, so you can test it out. Binary bloat is possible because you are exporting symbols that previously were known to be unused, and therefore stripped. If they're being exported, then it becomes possible for them to get called, so it may prevent them from getting stripped from the binary. Startup time regression is possible because of increased work on the part of the dynamic loader due to the extra symbols.

Also it's a no-go because of ODR violations it can incur with plugins.

Antoine

Darin Fisher

unread,
Jun 19, 2012, 5:20:48 PM6/19/12
to j...@chromium.org, Ken Kania, will...@chromium.org, zo...@chromium.org, chromium-dev, Ricardo Vargas, Jeffrey Yasskin
+1

On Tue, Jun 19, 2012 at 1:14 PM, Jói Sigurðsson <j...@chromium.org> wrote:

Victor Khimenko

unread,
Jun 19, 2012, 5:59:44 PM6/19/12
to kka...@google.com, will...@chromium.org, zo...@chromium.org, chromium-dev, Ricardo Vargas, Jói Sigurðsson, Jeffrey Yasskin
On Tue, Jun 19, 2012 at 11:53 PM, Ken Kania <kka...@google.com> wrote:
Thanks for the comment.  To give a little background, Zori is trying to enable chrome to load a DLL which can speak to chrome using a private automation interface.  For the interface, Zori is trying to decide between:

1) Exporting symbols from the executable and linking appropriately when building the automation DLL
class AUTO_EXPORT Tab {
  void LoadUrl(const std::string& url);
};
On mac, when building chrome we'd need to do something like -Wl,-exported_symbols_list, <file containing automation symbols>.  When building the shared object we'd need to use -bundle_loader.

On linux, I'm not sure how we could restrict chrome to just exporting a few symbols and not all of them through rdynamic.

-Wl,--retain-symbols-file=<file containing automation symbols>

Sigurður Ásgeirsson

unread,
Jun 19, 2012, 6:12:33 PM6/19/12
to kka...@google.com, will...@chromium.org, zo...@chromium.org, chromium-dev, Ricardo Vargas, Jói Sigurðsson, Jeffrey Yasskin
On Tue, Jun 19, 2012 at 3:53 PM, Ken Kania <kka...@google.com> wrote:
Thanks for the comment.  To give a little background, Zori is trying to enable chrome to load a DLL which can speak to chrome using a private automation interface.  For the interface, Zori is trying to decide between:

1) Exporting symbols from the executable and linking appropriately when building the automation DLL
class AUTO_EXPORT Tab {
  void LoadUrl(const std::string& url);
};
On mac, when building chrome we'd need to do something like -Wl,-exported_symbols_list, <file containing automation symbols>.  When building the shared object we'd need to use -bundle_loader.

On linux, I'm not sure how we could restrict chrome to just exporting a few symbols and not all of them through rdynamic.  Maybe we could strip everything out we don't need?  When building the shared object we shouldn't have to do anything since gcc won't complain about undefined symbols.

On windows, I think it should just work.


2) Don't do any exporting, just rely on the vtable and pass in a function pointer to instantiate an object (or something similar)
//  In the module:
void AUTO_EXPORT Init(Tab* (*create_tab_func)()) {
  create_tab_func()->LoadUrl("www.google.com");
}

// In shared header:
class Tab {
  virtual void LoadUrl(const std::string& url) = 0;
};

Please note that whichever approach you choose, you're best off passing only POD types across the module boundary. On Windows, your auxiliary DLL cannot share the same allocator as Chrome.DLL.

The practical implication of this is that code like this would tend to corrupt no less than one heap, and more likely two:
--- cut here ---
class Tab {
  virtual std::string GetTitle() = 0;
}

void foo(Tab* tab) {
  std::string title = tab->GetTitle();
}
--- cut here ---
Reply all
Reply to author
Forward
0 new messages