chrome: Support custom locales and resources paths
Describe the bug The cefclient sample application crashes unexpectedly when launched using a custom locales path.
To Reproduce Steps to reproduce the behavior:
- Change name of locales directory
- Execute: cefclient.exe --locales-dir-path
Expected behavior The cefclient sample application is started.
Versions (please complete the following information):
- OS: Windows 11 Version 23H2 (Build 22631.3880)
- CEF Version: 126.2.18
Are you using a fully qualified path for --locales-dir-path?
Yes, i use a fully qualified absolute path.
Using spotify releases I'm pinpointing this as: 05/07/2024 - 125.0.11 69ce47a works correctly 05/10/2024 - 125.0.14 44f7b57 crash The test is simple:
- download/unpack Sample Application
- cmd.exe:
cd
\Release rename locales locales2 cefclient --enable-logging=stderr --v=1 --locales-dir-path=%CD%\locales2 Notes.
- There are no spaces in path.
- Tested on Windows 10 x64 en-US using windows64 flavor.
69ce47a..44f7b57 are just 4 commits, and it is probably when --disable-chrome-runtime was added (hence making chrome runtime default), because 125.0.14 does not crash if --disable-chrome-runtime is passed. I think kLocalesDirPath is not passed up to chrome, base::PathService::Override(ui::DIR_LOCALES, locales_dir) is called only on alloy implementation. settings->locales_dir_path is probably set (I didn't modified a build to debug or LOG this), but not passed upstream.
Maybe adding similarily into ChromeMainDelegateCef::PreSandboxStartup a call to InitializeResourceBundle with a similar implementation will fix this. I suppose the DIR_RESOURCES is similarily affected.
Passing --enable-chrome-runtime to 125.0.11 crashes as well. So either this should be patched in Chrome (not recommended), or pair the paths override also in ChromeMainDelegateCef.
I think kLocalesDirPath is not passed up to chrome, base::PathService::Override(ui::DIR_LOCALES, locales_dir) is called only on alloy implementation.
We are setting the override here for Chrome.
Looks like our ordering is wrong here. The DIR_LOCALES values is queried via the call to ChromeMainDelegate::PreSandboxStartup, which occurs before we've configured it.
ui_base.dll!ui::ResourceBundle::GetLocaleFilePath(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & app_locale) Line 435 C++
ui_base.dll!ui::ResourceBundle::LocaleDataPakExists(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & locale) Line 389 C++
ui_base.dll!`anonymous namespace'::HasStringsForLocale(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & locale, const bool perform_io) Line 339 C++
ui_base.dll!l10n_util::CheckAndResolveLocale(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & locale, std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> * resolved_locale, const bool perform_io) Line 415 C++
ui_base.dll!l10n_util::CheckAndResolveLocale(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & locale, std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> * resolved_locale) Line 502 C++
ui_base.dll!l10n_util::GetApplicationLocaleInternal(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & pref_locale) Line 558 C++
ui_base.dll!l10n_util::GetApplicationLocale(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & pref_locale, bool set_icu_locale) Line 574 C++
ui_base.dll!l10n_util::GetApplicationLocale(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & pref_locale) Line 580 C++
ui_base.dll!ui::ResourceBundle::LoadLocaleResources(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & pref_locale, bool crash_on_failure) Line 459 C++
ui_base.dll!ui::ResourceBundle::InitSharedInstanceWithLocale(const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & pref_locale, ui::ResourceBundle::Delegate * delegate, ui::ResourceBundle::LoadResources load_resources) Line 295 C++
libcef.dll!ChromeMainDelegate::PreSandboxStartup() Line 1723 C++
> libcef.dll!ChromeMainDelegateCef::PreSandboxStartup() Line 384 C++
The patch doesn't fix problems on linux, another crash with callstack like this:
libcef.so!ImmediateCrash() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/immediate_crash.h:176) libcef.so!HandleFatal() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/logging.cc:1048) libcef.so!logging::LogMessage::Flush()::$_0::operator()() const() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/logging.cc:748) libcef.so!absl::cleanup_internal::Storagelogging::LogMessage::Flush()::$_0::InvokeCallback()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h:87) libcef.so!absl::Cleanup<absl::cleanup_internal::Tag, logging::LogMessage::Flush()::$_0>::~Cleanup()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/third_party/abseil-cpp/absl/cleanup/cleanup.h:106) libcef.so!logging::LogMessage::Flush()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/logging.cc:931) libcef.so!logging::LogMessage::~LogMessage()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/logging.cc:702) libcef.so!logging::(anonymous namespace)::DCheckLogMessage::~DCheckLogMessage()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/check.cc:167) libcef.so!logging::(anonymous namespace)::DCheckLogMessage::~DCheckLogMessage()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/check.cc:162) libcef.so!std::__Cr::default_deletelogging::LogMessage::operator()(logging::LogMessage*) const() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/third_party/libc++/src/include/__memory/unique_ptr.h:67) libcef.so!std::__Cr::unique_ptr<logging::LogMessage, std::__Cr::default_deletelogging::LogMessage >::reset(logging::LogMessage*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/third_party/libc++/src/include/__memory/unique_ptr.h:278) libcef.so!~CheckError() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/check.cc:350) libcef.so!ui::ResourceBundle::CreateImageSkia(int)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/ui/base/resource/resource_bundle.cc:1082) libcef.so!ui::ResourceBundle::GetImageNamed(int)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/ui/base/resource/resource_bundle.cc:594) libcef.so!ui::ResourceBundle::GetImageSkiaNamed(int)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/ui/base/resource/resource_bundle.cc:577) libcef.so!NotificationPlatformBridgeLinuxImpl::Init()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_platform_bridge_linux.cc:358) libcef.so!NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux(scoped_refptrdbus::Bus)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_platform_bridge_linux.cc:1199) libcef.so!NotificationPlatformBridgeLinux::NotificationPlatformBridgeLinux()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_platform_bridge_linux.cc:1194) libcef.so!std::__Cr::__unique_if<NotificationPlatformBridgeLinux>::__unique_single std::__Cr::make_unique<NotificationPlatformBridgeLinux>()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/third_party/libc++/src/include/__memory/unique_ptr.h:620) libcef.so!NotificationPlatformBridge::Create()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_platform_bridge_linux.cc:320) libcef.so!BrowserProcessImpl::CreateNotificationPlatformBridge()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/browser_process_impl.cc:1403) libcef.so!BrowserProcessImpl::notification_platform_bridge()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/browser_process_impl.cc:857) libcef.so!(anonymous namespace)::GetSystemNotificationPlatformBridge(Profile*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_platform_bridge_delegator.cc:80) libcef.so!NotificationPlatformBridgeDelegator::NotificationPlatformBridgeDelegator(Profile*, base::OnceCallback<void ()>)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_platform_bridge_delegator.cc:103) libcef.so!std::__Cr::__unique_if<NotificationPlatformBridgeDelegator>::__unique_single std::__Cr::make_unique<NotificationPlatformBridgeDelegator, base::raw_ptr<Profile, (partition_alloc::internal::RawPtrTraits)0>&, base::OnceCallback<void ()> >(base::raw_ptr<Profile, (partition_alloc::internal::RawPtrTraits)0>&, base::OnceCallback<void ()>&&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/third_party/libc++/src/include/__memory/unique_ptr.h:620) libcef.so!NotificationDisplayServiceImpl::NotificationDisplayServiceImpl(Profile*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_display_service_impl.cc:128) libcef.so!std::__Cr::__unique_if<NotificationDisplayServiceImpl>::__unique_single std::__Cr::make_unique<NotificationDisplayServiceImpl, Profile*>(Profile*&&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/third_party/libc++/src/include/__memory/unique_ptr.h:620) libcef.so!NotificationDisplayServiceFactory::BuildServiceInstanceForBrowserContext(content::BrowserContext*) const() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_display_service_factory.cc:47) libcef.so!BrowserContextKeyedServiceFactory::BuildServiceInstanceFor(void*) const() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/content/browser_context_keyed_service_factory.cc:106) libcef.so!KeyedServiceTemplatedFactory<KeyedService>::GetServiceForContext(void*, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/core/keyed_service_templated_factory.cc:104) libcef.so!BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(content::BrowserContext*, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/content/browser_context_keyed_service_factory.cc:57) libcef.so!NotificationDisplayServiceFactory::GetForProfile(Profile*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/notification_display_service_factory.cc:23) libcef.so!PlatformNotificationServiceImpl::GetDisplayedNotifications(base::OnceCallback<void (std::__Cr::set<std::__Cr::basic_string<char, std::__Cr::char_traits
, std::__Cr::allocator >, std::__Cr::less<std::__Cr::basic_string<char, std::__Cr::char_traits , std::__Cr::allocator > >, std::__Cr::allocator<std::__Cr::basic_string<char, std::__Cr::char_traits , std::__Cr::allocator > > >, bool)>)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/notifications/platform_notification_service_impl.cc:340) libcef.so!content::PlatformNotificationContextImpl::Initialize()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/notifications/platform_notification_context_impl.cc:144) libcef.so!content::StoragePartitionImpl::Initialize(content::StoragePartitionImpl*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/storage_partition_impl.cc:1417) libcef.so!content::StoragePartitionImplMap::Get(content::StoragePartitionConfig const&, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/storage_partition_impl_map.cc:350) libcef.so!content::BrowserContext::GetStoragePartition(content::StoragePartitionConfig const&, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/browser_context.cc:137) libcef.so!content::BrowserContext::GetDefaultStoragePartition()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/browser_context.cc:180) libcef.so!OptimizationGuideKeyedService::Initialize()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc:340) libcef.so!OptimizationGuideKeyedService::OptimizationGuideKeyedService(content::BrowserContext*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/optimization_guide/optimization_guide_keyed_service.cc:287) libcef.so!std::__Cr::__unique_if<OptimizationGuideKeyedService>::__unique_single std::__Cr::make_unique<OptimizationGuideKeyedService, content::BrowserContext*&>(content::BrowserContext*&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/third_party/libc++/src/include/__memory/unique_ptr.h:620) libcef.so!OptimizationGuideKeyedServiceFactory::BuildServiceInstanceForBrowserContext(content::BrowserContext*) const() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.cc:64) libcef.so!BrowserContextKeyedServiceFactory::BuildServiceInstanceFor(void*) const() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/content/browser_context_keyed_service_factory.cc:106) libcef.so!KeyedServiceTemplatedFactory<KeyedService>::GetServiceForContext(void*, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/core/keyed_service_templated_factory.cc:104) libcef.so!BrowserContextKeyedServiceFactory::GetServiceForBrowserContext(content::BrowserContext*, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/content/browser_context_keyed_service_factory.cc:57) libcef.so!OptimizationGuideKeyedServiceFactory::GetForProfile(Profile*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.cc:29) libcef.so!safe_browsing::ClientSideDetectionServiceFactory::BuildServiceInstanceForBrowserContext(content::BrowserContext*) const() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/safe_browsing/client_side_detection_service_factory.cc:57) libcef.so!BrowserContextKeyedServiceFactory::BuildServiceInstanceFor(void*) const() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/content/browser_context_keyed_service_factory.cc:106) libcef.so!KeyedServiceTemplatedFactory<KeyedService>::GetServiceForContext(void*, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/core/keyed_service_templated_factory.cc:104) libcef.so!BrowserContextKeyedServiceFactory::CreateServiceNow(void*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/content/browser_context_keyed_service_factory.cc:138) libcef.so!DependencyManager::CreateContextServices(void*, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/core/dependency_manager.cc:129) libcef.so!BrowserContextDependencyManager::DoCreateBrowserContextServices(content::BrowserContext*, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/content/browser_context_dependency_manager.cc:46) libcef.so!BrowserContextDependencyManager::CreateBrowserContextServices(content::BrowserContext*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/components/keyed_service/content/browser_context_dependency_manager.cc:31) libcef.so!ProfileImpl::OnLocaleReady(Profile::CreateMode)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/profiles/profile_impl.cc:1150) libcef.so!ProfileImpl::OnPrefsLoaded(Profile::CreateMode, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/profiles/profile_impl.cc:1195) libcef.so!ProfileImpl::ProfileImpl(base::FilePath const&, Profile::Delegate*, Profile::CreateMode, base::Time, scoped_refptrbase::SequencedTaskRunner)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/profiles/profile_impl.cc:526) libcef.so!Profile::CreateProfile(base::FilePath const&, Profile::Delegate*, Profile::CreateMode)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/profiles/profile_impl.cc:369) libcef.so!ProfileManager::CreateProfileHelper(base::FilePath const&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/profiles/profile_manager.cc:1247) libcef.so!ProfileManager::CreateAndInitializeProfile(base::FilePath const&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/profiles/profile_manager.cc:1794) libcef.so!ProfileManager::GetProfile(base::FilePath const&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/profiles/profile_manager.cc:714) libcef.so!GetStartupProfile(base::FilePath const&, base::CommandLine const&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/ui/startup/startup_browser_creator.cc:1732) libcef.so!(anonymous namespace)::CreateInitialProfile(base::FilePath const&, base::CommandLine const&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/chrome_browser_main.cc:489) libcef.so!ChromeBrowserMainParts::PreMainMessageLoopRunImpl()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/chrome_browser_main.cc:1610) libcef.so!ChromeBrowserMainParts::PreMainMessageLoopRun()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/chrome/browser/chrome_browser_main.cc:1242) libcef.so!content::BrowserMainLoop::PreMainMessageLoopRun()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/browser_main_loop.cc:995) libcef.so!int base::internal::DecayedFunctorTraits<int (content::BrowserMainLoop::)(), content::BrowserMainLoop>::Invoke<int (content::BrowserMainLoop::)(), content::BrowserMainLoop>(int (content::BrowserMainLoop::)(), content::BrowserMainLoop&&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/functional/bind_internal.h:738) libcef.so!int base::internal::InvokeHelper<false, base::internal::FunctorTraits<int (content::BrowserMainLoop::&&)(), content::BrowserMainLoop>, int, 0ul>::MakeItSo<int (content::BrowserMainLoop::)(), std::__Cr::tuple<base::internal::UnretainedWrapper<content::BrowserMainLoop, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0> >>(int (content::BrowserMainLoop::&&)(), std::__Cr::tuple<base::internal::UnretainedWrapper<content::BrowserMainLoop, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0> >&&)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/functional/bind_internal.h:930) libcef.so!int base::internal::Invoker<base::internal::FunctorTraits<int (content::BrowserMainLoop::&&)(), content::BrowserMainLoop>, base::internal::BindState<true, true, false, int (content::BrowserMainLoop::)(), base::internal::UnretainedWrapper<content::BrowserMainLoop, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0> >, int ()>::RunImpl<int (content::BrowserMainLoop::)(), std::__Cr::tuple<base::internal::UnretainedWrapper<content::BrowserMainLoop, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0> >, 0ul>(int (content::BrowserMainLoop::&&)(), std::__Cr::tuple<base::internal::UnretainedWrapper<content::BrowserMainLoop, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0> >&&, std::__Cr::integer_sequence<unsigned long, 0ul>)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/functional/bind_internal.h:1067) libcef.so!base::internal::Invoker<base::internal::FunctorTraits<int (content::BrowserMainLoop::&&)(), content::BrowserMainLoop*>, base::internal::BindState<true, true, false, int (content::BrowserMainLoop::)(), base::internal::UnretainedWrapper<content::BrowserMainLoop, base::unretained_traits::MayNotDangle, (partition_alloc::internal::RawPtrTraits)0> >, int ()>::RunOnce(base::internal::BindStateBase)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/functional/bind_internal.h:980) libcef.so!base::OnceCallback<int ()>::Run() &&() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/base/functional/callback.h:156) libcef.so!content::StartupTaskRunner::RunAllTasksNow()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/startup_task_runner.cc:42) libcef.so!content::BrowserMainLoop::CreateStartupTasks()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/browser_main_loop.cc:898) libcef.so!content::BrowserMainRunnerImpl::Initialize(content::MainFunctionParams)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/browser/browser_main_runner_impl.cc:140) libcef.so!CefMainRunner::RunMainProcess(content::MainFunctionParams)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/cef/libcef/browser/main_runner.cc:540) libcef.so!ChromeMainDelegateCef::RunProcess(std::__Cr::basic_string<char, std::__Cr::char_traits , std::__Cr::allocator > const&, content::MainFunctionParams)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/cef/libcef/common/chrome/chrome_main_delegate_cef.cc:464) libcef.so!content::RunBrowserProcessMain(content::MainFunctionParams, content::ContentMainDelegate*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/app/content_main_runner_impl.cc:717) libcef.so!content::ContentMainRunnerImpl::RunBrowser(content::MainFunctionParams, bool)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/app/content_main_runner_impl.cc:1303) libcef.so!content::ContentMainRunnerImpl::Run()() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/app/content_main_runner_impl.cc:1155) libcef.so!content::ContentMainRun(content::ContentMainRunner*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/content/app/content_main.cc:326) libcef.so!CefMainRunner::ContentMainRun(bool*, base::OnceCallback<void ()>)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/cef/libcef/browser/main_runner.cc:505) libcef.so!CefMainRunner::Initialize(CefStructBase<CefSettingsTraits>, scoped_refptr<CefApp>, CefMainArgs const&, void, bool*, base::OnceCallback<void ()>)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/cef/libcef/browser/main_runner.cc:286) libcef.so!CefContext::Initialize(CefMainArgs const&, CefStructBase<CefSettingsTraits> const&, scoped_refptr<CefApp>, void*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/cef/libcef/browser/context.cc:506) libcef.so!CefInitialize(CefMainArgs const&, CefStructBase<CefSettingsTraits> const&, scoped_refptr<CefApp>, void*)() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/cef/libcef/browser/context.cc:330) libcef.so!cef_initialize() (/home/JCYang/dev_home/cef_workspace/chromium_git/chromium/src/cef/libcef_dll/libcef_dll.cc:114) CefInitialize(const CefMainArgs & args, const CefSettings & settings, CefRefPtr application, void * windows_sandbox_info) (/home/JCYang/dev_home/CMClient/3rd/cef/64/libcef_dll/wrapper/libcef_dll_wrapper.cc:102) wxWebViewChromium::StartUp(int & code, const std::__cxx11::wstring & AppPath, const std::__cxx11::wstring & LogPath, const std::__cxx11::wstring & CachePath) (/home/JCYang/dev_home/CMClient/CMClient/guilib/webview_chromium3.cpp:1107) cmWebViewPanel::startup(const std::__cxx11::wstring & strAppPath, const std::__cxx11::wstring & strLogPath, const std::__cxx11::wstring & CachePath) (/home/JCYang/dev_home/CMClient/CMClient/guilib/cmwebviewpanel.cpp:720) CMClientApp::OnInit(CMClientApp * const this) (/home/JCYang/dev_home/CMClient/CMClient/main/main.cpp:570) wxAppConsoleBase::CallOnInit(wxAppConsoleBase * const this) (/home/JCYang/dev_home/CMClient/3rd/wx/include/wx/app.h:93) wxEntry(int & argc, wxChar ** argv) (/home/JCYang/dev_home/CMClient/3rd/wx/src/common/init.cpp:481) wxEntry(int & argc, char ** argv) (/home/JCYang/dev_home/CMClient/3rd/wx/src/common/init.cpp:509) main(int argc, char ** argv) (/home/JCYang/dev_home/CMClient/CMClient/main/main.cpp:163)
It looks like Chrome is using base::DIR_ASSETS instead of chrome::DIR_RESOURCES in GetResourcesPakFilePath and LazyInitIcuDataFile. This changed in 2021 (Chromium commit here).
The location of snapshot_blob.bin is also complicated and platform-specific (DIR_EXE on Linux (code), app bundle framework location on MacOS (code)).
One complication with overriding base::DIR_ASSETS on Linux is that we're loading binaries from that directory due to issue #1936 and issue #3213. Currently, base::DIR_ASSETS on Linux is configured to the libcef module path. If we set base::DIR_ASSETS based on the --resources-dir-path value then the location of these binaries will need to change accordingly. Meanwhile, Windows is still using DIR_MODULE (libcef module path) for these DLLs.
We likely want to keep the current binary loading behavior unchanged on Linux.
@JCYang Please explain your use case for customizing the resources-dir-path. Given the complexity described above I'm inclined to just remove this configuration option and require resources to be placed next to the libcef module on Linux and Windows, and in the appropriate app bundle framework location on MacOS.
We have a fairly straightforward use-case:
We ship both 32-bit and 64-bit CEF binaries in the same application (on Windows), and since the chromium resources are the same for both, we use --resources-dir-path to point both to one canonical path, instead of shipping the same resources twice or doing some sort of redirect nonsense. Same with locales and --locales-dir-path.
Also just for completion sake, while --locales-dir-path seems to be working, --resources-dir-path is still broken in CEF 131.2.7+g9a14dc9+chromium-131.0.6778.86:
We ship both 32-bit and 64-bit CEF binaries in the same application (on Windows), and since the chromium resources are the same for both
Interesting. The *.bin files (icu, v8, etc) are not the same for both architectures. Where do you put those?
Note that *.pak files being the same would be considered a happy coincidence and probably not by design.
Everything but *.pak files are next to libcef as normal; we're just moving resources and locales.
We know that it's maybe not deliberate they're shared between arches, but we haven't had an issue with it yet, and we've been doing it since like CEF 86, so.
Just to express interest in this issue: we have an application with 1000s of dlls and other files including 3rd party libraries. Every little bit helps to keep the application folder tidy, and avoid possible clashes and confusion.
before M128, if you set chrome_runtime = true, then _cef_settings_t.resources_dir_path doesn't work at all. starting from M128, _cef_settings_t.resources_dir_path never work again, I think this is a bug introduced from chrome runtime bootstrap.
This is still an issue in the current stable release: CEF 136.1.6+g1ac1b14+chromium-136.0.7103.114
Is it possible this will be fixed at some point?
My current thinking on this point is that we will remove resources_dir_path / locales_dir_path settings and instead support the complete extraction of "Chromium Embedded Framework.framework" to an external directory (outside the app bundle). This extracted directory will need to contain the default framework directory structure. The app bundle will then contain a symlink pointing to the external framework location.
For example:
[app].app/Contents/Frameworks/Chromium Embedded Framework.framework ->
/System/Library/Frameworks/Chromium Embedded Framework.framework/Versions/136.1.6
We would likely also move the Helpers folder up one directory (out of the framework directory) in that case.
NOTE: In the not unlikely case that the directory symlink doesn't work we would instead symlink the individual files to the external locations (as is normally done with a versioned framework pointing to "Current", "A", etc). In that case the Helpers folder could remain in its current location.
It’s also possible that symbolic links outside the app bundle will fail notarization, in which case we can implement similar logic with CefScopedLibraryLoader instead.
Gatekeeper also rejects apps containing symbolic links that: point outside the app bundle, except to locations in /System and /Library.
From Gatekeeper Changes in macOS 10.11 and Later
We might be able to use the /Library/Frameworks directory (docs) if the installer runs as root.