diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-08 22:30:58 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-08 22:30:58 +0000 |
commit | a5d7bb818ff6595c2450dae7cff77ed74460fb41 (patch) | |
tree | f84ffb001ebc3a3da2ba8f22b5a46e13791cda59 /chrome/browser/zygote_main_linux.cc | |
parent | f9447c06b37a80551ac929b5b93a076b5509780c (diff) | |
download | chromium_src-a5d7bb818ff6595c2450dae7cff77ed74460fb41.zip chromium_src-a5d7bb818ff6595c2450dae7cff77ed74460fb41.tar.gz chromium_src-a5d7bb818ff6595c2450dae7cff77ed74460fb41.tar.bz2 |
Linux: work around broken dlsym's.
It appears that Nvidia's libGL.so is overriding dlopen/dlsym with
versions that don't fully function. So far, all the users reporting
this have been running Gentoo, but it might just be that they have
up-to-date drivers. The report[1] suggests that all drivers >= 180
have this issue.
[1] http://www.nvnews.net/vbulletin/showthread.php?t=132259
BUG=16800
http://codereview.chromium.org/201055
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25671 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/zygote_main_linux.cc')
-rw-r--r-- | chrome/browser/zygote_main_linux.cc | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/chrome/browser/zygote_main_linux.cc b/chrome/browser/zygote_main_linux.cc index 2592209..2fc525d 100644 --- a/chrome/browser/zygote_main_linux.cc +++ b/chrome/browser/zygote_main_linux.cc @@ -281,6 +281,8 @@ static bool g_am_zygote_or_renderer = false; // We also considered patching the function in place, but this would again by // platform specific and the above technique seems to work well enough. +static void WarnOnceAboutBrokenDlsym(); + struct tm* localtime(const time_t* timep) { if (g_am_zygote_or_renderer) { static struct tm time_struct; @@ -291,8 +293,22 @@ struct tm* localtime(const time_t* timep) { } else { typedef struct tm* (*LocaltimeFunction)(const time_t* timep); static LocaltimeFunction libc_localtime; - if (!libc_localtime) + static bool have_libc_localtime = false; + if (!have_libc_localtime) { libc_localtime = (LocaltimeFunction) dlsym(RTLD_NEXT, "localtime"); + have_libc_localtime = true; + } + + if (!libc_localtime) { + // http://code.google.com/p/chromium/issues/detail?id=16800 + // + // Nvidia's libGL.so overrides dlsym for an unknown reason and replaces + // it with a version which doesn't work. In this case we'll get a NULL + // result. There's not a lot we can do at this point, so we just bodge it! + WarnOnceAboutBrokenDlsym(); + + return gmtime(timep); + } return libc_localtime(timep); } @@ -306,13 +322,35 @@ struct tm* localtime_r(const time_t* timep, struct tm* result) { typedef struct tm* (*LocaltimeRFunction)(const time_t* timep, struct tm* result); static LocaltimeRFunction libc_localtime_r; - if (!libc_localtime_r) + static bool have_libc_localtime_r = false; + if (!have_libc_localtime_r) { libc_localtime_r = (LocaltimeRFunction) dlsym(RTLD_NEXT, "localtime_r"); + have_libc_localtime_r = true; + } + + if (!libc_localtime_r) { + // See |localtime|, above. + WarnOnceAboutBrokenDlsym(); + + return gmtime_r(timep, result); + } return libc_localtime_r(timep, result); } } +// See the comments at the callsite in |localtime| about this function. +static void WarnOnceAboutBrokenDlsym() { + static bool have_shown_warning = false; + if (!have_shown_warning) { + LOG(ERROR) << "Your system is broken: dlsym doesn't work! This has been " + "reported to be caused by Nvidia's libGL. You should expect " + "time related functions to misbehave. " + "http://code.google.com/p/chromium/issues/detail?id=16800"; + have_shown_warning = true; + } +} + static bool MaybeEnterChroot() { const char* const sandbox_fd_string = getenv("SBX_D"); if (sandbox_fd_string) { |