summaryrefslogtreecommitdiffstats
path: root/chrome/browser/zygote_main_linux.cc
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-08 22:30:58 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-08 22:30:58 +0000
commita5d7bb818ff6595c2450dae7cff77ed74460fb41 (patch)
treef84ffb001ebc3a3da2ba8f22b5a46e13791cda59 /chrome/browser/zygote_main_linux.cc
parentf9447c06b37a80551ac929b5b93a076b5509780c (diff)
downloadchromium_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.cc42
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) {