From d7f8dad941a8d06f1f53d0e285c1f2d9af28a8fe Mon Sep 17 00:00:00 2001 From: dominickn Date: Tue, 1 Dec 2015 20:56:51 -0800 Subject: [Mac] Increment app shortcut version numbers. https://crrev.com/1413863003 statically links libc++.a on Mac. This causes app shims created before the static linking to fail to launch on Chromium built after the static linking. The launch failures are caused by substantial memory corruptions in the app_mode::ChromeAppModeInfo struct when it is passed from the shim launcher to the Chromium dylib at startup, as the shim is linking against the system C++ library while Chromium is now linked to its own libc++. This CL increments the shortcut version numbers, which will cause Chromium to rebuild shims when it is launched. However, shims which are launched without Chromium running will continue to fail until Chromium is launched, at which point the shims will be rebuilt. To counter this, the ChromeAppModeStart entry point for shims is now versioned; by incrementing the function version number, all old shims will automatically be rebuilt on their next launch. BUG=561205 Review URL: https://codereview.chromium.org/1487503002 Cr-Commit-Position: refs/heads/master@{#362634} --- chrome/app_shim/app_mode_loader_mac.mm | 8 +++++++- chrome/app_shim/chrome_main_app_mode_mac.mm | 12 +++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'chrome/app_shim') diff --git a/chrome/app_shim/app_mode_loader_mac.mm b/chrome/app_shim/app_mode_loader_mac.mm index 16e7f7e..1d55ffc 100644 --- a/chrome/app_shim/app_mode_loader_mac.mm +++ b/chrome/app_shim/app_mode_loader_mac.mm @@ -31,6 +31,12 @@ namespace { typedef int (*StartFun)(const app_mode::ChromeAppModeInfo*); +// The name of the entry point in the Framework. This name is dynamically +// queried at shim launch to allow the shim to connect and run. +// The function is versioned in case we need to obsolete and rebuild the shim +// before it loads, e.g. see https://crbug.com/561205. +const char kStartFunName[] = "ChromeAppModeStart_v4"; + int LoadFrameworkAndStart(app_mode::ChromeAppModeInfo* info) { using base::SysNSStringToUTF8; using base::SysNSStringToUTF16; @@ -138,7 +144,7 @@ int LoadFrameworkAndStart(app_mode::ChromeAppModeInfo* info) { void* cr_dylib = dlopen(framework_shlib_path.value().c_str(), RTLD_LAZY); if (cr_dylib) { // Find the entry point. - ChromeAppModeStart = (StartFun)dlsym(cr_dylib, "ChromeAppModeStart"); + ChromeAppModeStart = (StartFun)dlsym(cr_dylib, kStartFunName); if (!ChromeAppModeStart) LOG(ERROR) << "Couldn't get entry point: " << dlerror(); } else { diff --git a/chrome/app_shim/chrome_main_app_mode_mac.mm b/chrome/app_shim/chrome_main_app_mode_mac.mm index 60b60a39..f2d24c7 100644 --- a/chrome/app_shim/chrome_main_app_mode_mac.mm +++ b/chrome/app_shim/chrome_main_app_mode_mac.mm @@ -565,13 +565,19 @@ void AppShimController::SendSetAppHidden(bool hidden) { extern "C" { // |ChromeAppModeStart()| is the point of entry into the framework from the app -// mode loader. +// mode loader. There are cases where the Chromium framework may have changed in +// a way that is incompatible with an older shim (e.g. change to libc++ library +// linking). The function name is versioned to provide a way to force shim +// upgrades if they are launched before an updated version of Chromium can +// upgrade them; the old shim will not be able to dyload the new +// ChromeAppModeStart, so it will fall back to the upgrade path. See +// https://crbug.com/561205. __attribute__((visibility("default"))) -int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info); +int ChromeAppModeStart_v4(const app_mode::ChromeAppModeInfo* info); } // extern "C" -int ChromeAppModeStart(const app_mode::ChromeAppModeInfo* info) { +int ChromeAppModeStart_v4(const app_mode::ChromeAppModeInfo* info) { base::CommandLine::Init(info->argc, info->argv); base::mac::ScopedNSAutoreleasePool scoped_pool; -- cgit v1.1