Implement support for NetworkService

Issue #2622 resolved
Mike Wiedenbauer created an issue

Chromium is moving from an in-process network stack implementation to a separate NetworkService process.

Tracking issue and design docs at https://bugs.chromium.org/p/chromium/issues/detail?id=598073

Related embedder-dev@ thread: https://groups.google.com/a/chromium.org/d/msg/embedder-dev/DYE94KHLMx4/g_vhK2T4CAAJ

Chromium NetworkService status updates are being sent to the services-dev@ mailing list. Here's the most recent update: https://groups.google.com/a/chromium.org/d/msg/services-dev/bhiYEx0d10I/c-VgO4scBgAJ. Based on this update I'm guessing the old code path will be removed after M75 branches (mid-April).

Official response

  • Marshall Greenblatt

    Current status:

    • NetworkService is now enabled by default.
    • The old network implementation has been deleted in master and newer branches. M76 (3809) is the last branch to support --disable-features=NetworkService.
    • Related known/open issues can be found here.

    Summary of changes (see commit log for a full list of changes):

    • Usage has changed as follows:

      • All cache_path values must be relative to a new CefSettings.root_cache_path value.
      • CefCookieManager callbacks are now executed on the UI thread (previously the IO thread).
    • The following methods have been removed:

      • CefCookieManager::CreateManager
      • CefCookieManager::GetBlockingManager
      • CefCookieManager::SetStoragePath
      • CefRequestContextHandler::GetCookieManager
    • The following methods have been added:

      • CefFrame::CreateURLRequest
      • GetResourceRequestHandler in CefRequestHandler and CefRequestContextHandler
    • The following methods have been moved/renamed:

      • CefRequestContext::GetDefaultCookieManager to GetCookieManager.
      • CefRequestHandler::* to CefResourceRequestHandler::*

    Other related enhancements (not blocking NetworkService by default):

    • Move certificate-related callbacks to CefResourceRequestHandler (OnCertificateError, OnSelectClientCertificate).
    • Move CefServer to network process?
    • API redundancy: CefRequestCallback has same functionality as CefCallback (issue #1861)

Comments (116)

  1. Marshall Greenblatt

    @shagkur Can you share any progress on this issue? I'm planning to pick this up shortly as well, given the approaching old path removal deadline.

  2. Marshall Greenblatt

    Key methods for NetworkService initialization:

    Request handling/interception with NetworkService:

    Custom schemes are handled using URLLoaderFactory (for example, ExtensionURLLoaderFactory). These objects are created via:

    Existing URLLoaderFactory interfaces can be intercepted using WillCreateURLLoaderFactory.

    Arbitrary requests can be intercepted using URLLoaderRequestInterceptor (for example, OfflinePageURLLoaderRequestInterceptor). These objects are created via WillCreateURLLoaderRequestInterceptors.

  3. Marshall Greenblatt

    Current status:

    • NetworkService is now enabled by default.
    • The old network implementation has been deleted in master and newer branches. M76 (3809) is the last branch to support --disable-features=NetworkService.
    • Related known/open issues can be found here.

    Summary of changes (see commit log for a full list of changes):

    • Usage has changed as follows:

      • All cache_path values must be relative to a new CefSettings.root_cache_path value.
      • CefCookieManager callbacks are now executed on the UI thread (previously the IO thread).
    • The following methods have been removed:

      • CefCookieManager::CreateManager
      • CefCookieManager::GetBlockingManager
      • CefCookieManager::SetStoragePath
      • CefRequestContextHandler::GetCookieManager
    • The following methods have been added:

      • CefFrame::CreateURLRequest
      • GetResourceRequestHandler in CefRequestHandler and CefRequestContextHandler
    • The following methods have been moved/renamed:

      • CefRequestContext::GetDefaultCookieManager to GetCookieManager.
      • CefRequestHandler::* to CefResourceRequestHandler::*

    Other related enhancements (not blocking NetworkService by default):

    • Move certificate-related callbacks to CefResourceRequestHandler (OnCertificateError, OnSelectClientCertificate).
    • Move CefServer to network process?
    • API redundancy: CefRequestCallback has same functionality as CefCallback (issue #1861)
  4. Marshall Greenblatt

    @shagkur if you would like to work on the CefURLRequest support feel free to use my PR as a starting point -- we can merge all of the commits at some point in the future.

  5. Mike Wiedenbauer reporter

    @magreenblatt Sorry for not being much responsive these days, but i'm currently at an on-site visit for my company and can't do much on this topic. Next week looks better and i'll start on it on your branch (already had a quick look at it today)

  6. Marshall Greenblatt

    Cookies can be accessed/modified from the browser process using StoragePartition::GetCookieManagerForBrowserProcess, but that doesn't provide the same proxy capabilities that we currently offer via CefRequestContextHandler::GetCookieHandler. We might need to register some handlers in the network service/process directly.

    Call stack for creation of the NetworkContext:

    >   libcef.dll!ProfileNetworkContextService::CreateNetworkContextParams(bool in_memory, const base::FilePath & relative_partition_path) Line 371    C++
        libcef.dll!ProfileNetworkContextService::CreateNetworkContext(bool in_memory, const base::FilePath & relative_partition_path) Line 154  C++
        libcef.dll!Profile::CreateNetworkContext(bool in_memory, const base::FilePath & relative_partition_path) Line 258   C++
        libcef.dll!CefContentBrowserClient::CreateNetworkContext(content::BrowserContext * context, bool in_memory, const base::FilePath & relative_partition_path) Line 1222   C++
        content.dll!content::StoragePartitionImpl::InitNetworkContext() Line 1412   C++
        content.dll!content::StoragePartitionImpl::GetNetworkContext() Line 803 C++
        content.dll!content::URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread(mojo::InterfaceRequest<network::mojom::URLLoaderFactory> network_factory_request, bool is_corb_enabled) Line 301 C++
        content.dll!content::URLLoaderFactoryGetter::HandleFactoryRequests() Line 152   C++
        content.dll!content::URLLoaderFactoryGetter::Initialize(content::StoragePartitionImpl * partition) Line 143 C++
        content.dll!content::StoragePartitionImpl::Create(content::BrowserContext * context, bool in_memory, const base::FilePath & relative_partition_path, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & partition_domain) Line 726    C++
        content.dll!content::StoragePartitionImplMap::Get(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & partition_domain, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & partition_name, bool in_memory, bool can_create) Line 397 C++
        content.dll!content::`anonymous namespace'::GetStoragePartitionFromConfig(content::BrowserContext * browser_context, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & partition_domain, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & partition_name, bool in_memory, bool can_create) Line 218  C++
        content.dll!content::BrowserContext::GetStoragePartition(content::BrowserContext * browser_context, content::SiteInstance * site_instance, bool can_create) Line 446    C++
        content.dll!content::BrowserContext::GetDefaultStoragePartition(content::BrowserContext * browser_context) Line 478 C++
        libcef.dll!CefBrowserContextImpl::Initialize() Line 309 C++
        libcef.dll!CefRequestContextImpl::Initialize() Line 613 C++
        libcef.dll!CefRequestContextImpl::CreateGlobalRequestContext(const CefStructBase<CefRequestContextSettingsTraits> & settings) Line 164  C++
        libcef.dll!CefBrowserMainParts::PreMainMessageLoopRun() Line 199    C++
    

    CefContentBrowserClient::CreateNetworkContext calls Profile::CreateNetworkContext which results in a call to ProfileNetworkContextService::CreateNetworkContextParams which sets CookieManagerParams values.

    The NetworkContext is uniquely identified by these parameters:

        content::BrowserContext* context,
        bool in_memory,
        const base::FilePath& relative_partition_path
    

    The |relative_partition_path| value, if non-empty, will be appended to the BrowserContext's cache path.

    If we use BrowserContext::GetStoragePartition(BrowserContext* browser_context, SiteInstance* site_instance) instead of GetDefaultStoragePartition then we can further customize the configuration by implementing ContentBrowserClient::GetStoragePartitionConfigForSite. However, it might not make sense to use SiteInstance given the renderer process implications (see the docs on that class).

  7. Marshall Greenblatt

    It's probably time that we move to the intended Chromium model (see discussion here) and get rid of the special CefRequestContextHandler::GetCookieHandler handling (which currently requires all kinds of hacks in Chromium code to implement SiteInstance proxying). Just create your CefBrowser with a different CefRequestContext and cache_path if you want separate cookie storage. We can then re-implement CefCookieManager to use StoragePartition::GetCookieManagerForBrowserProcess for access to the underlying cookie storage.

  8. Marshall Greenblatt

    Add initial NetworkService support (see issue #2622).

    This change adds an --enable-network-service command-line flag to run with NetworkService enabled.

    To test: Run cefclient --enable-network-service --disable-extensions. The application should start, load a website and exit without crashing. Network-related handlers (for cookies, schemes, requests, etc) and extensions are not expected to work yet.

    There should be no functional change when running without the NetworkService enabled.

    → <<cset 6b2c1fe9693f>>

  9. Marshall Greenblatt

    Remove methods that modify cookie storage at runtime (see issue #2622).

    This change removes cookie and request handler functionality that will not supported by the NetworkService. Specifically, it is no longer possible to change cookie storage locations at runime by returning a different CefCookieManager for an already initialized CefRequestContext. After this change you will need to use a separate CefRequestContext when creating a CefBrowser if you require separate cookie storage.

    The following methods have been removed: - CefCookieManager::CreateManager - CefCookieManager::GetBlockingManager - CefCookieManager::SetStoragePath - CefRequestContextHandler::GetCookieManager

    The following methods have been renamed: - CefRequestContext::GetDefaultCookieManager to GetCookieManager.

    This change substantially simplifies the network implementation in CEF because it is no longer necessary to proxy objects that are normally owned by Chromium. Chromium patches that are no longer necessary will be removed as a follow-up commit.

    To test: Verify that ceftests --gtest_filter=-PluginTest.* pass with NetworkService disabled. Plugin tests will be fixed in a follow-up commit.

    → <<cset a23e8452443d>>

  10. Marshall Greenblatt

    Move the frame/handler association to CefResourceContext (see issue #2622).

    A CefBrowserHostImpl is created using a CefRequestContextImpl that may have a CefRequestContextHandler. Multiple CefRequestContextImpl may share the same underlying CefBrowserContext which owns a CefResourceContext. IO-thread callbacks from Chromium are often associated with a CefResourceContext and the target frame is identified using render_process_id/render_frame_id routing IDs.

    This change forwards frame create/delete notifications from CefBrowserHostImpl (or CefMimeHandlerViewGuestDelegate) to CefResourceContext so that it can properly resolve the association from routing ID to Handler when queried from CefPluginServiceFilter::IsPluginAvailable.

    To test: Verify that all ceftests pass with NetworkService disabled.

    → <<cset ea27dff33839>>

  11. Marshall Greenblatt

    Enforce cache_path requirements for NetworkService (see issue #2622).

    This change adds a new CefSettings.root_cache_path value that must be either equal to or a parent directory of all CefSettings.cache_path and CefRequestContextSettings.cache_path values. The sandbox may block read/write access from the NetworkService to directories that do not meet this requirement.

    To test: Run cefclient with a combination of the following flags:

    --cache-path=c:\temp\cache Cache data should be persisted to the specified directory.

    --request-context-per-browser A separate numbered cache directory should be created underneath the cache-path directory for each new browser instance.

    --enable-network-service --disable-extensions Same tests, but with NetworkService enabled.

    Known issues: - When NetworkService is enabled a C:\temp\cache\cache\Cache directory is created (should be C:\temp\cache\Cache).

    → <<cset b65f336f8126>>

  12. Mike Wiedenbauer reporter

    @magreenblatt Is it still valid to retrieve the CefRequestContext(Impl) and hence the CefBrowserContext via the "GetRequestContextOnUIThread" function in CefURLRequest? Because URLLoader and SimpleURLLoader need a URLLoaderFactory which, if i understand CefBrowserContext correctly, is provided by that class?

  13. Marshall Greenblatt

    @shagkur The logic in GetRequestContextOnUIThread for retrieving the CefRequestContextImpl and CefBrowserContext looks fine. You should then be able to retrieve the URLLoaderFactory via content::BrowserContext::GetDefaultStoragePartition(browser_context)->GetURLLoaderFactoryForBrowserProcess().

  14. Marshall Greenblatt

    Add CookieManagerImpl for NetworkService (see issue #2622).

    To test: Run ceftests --gtest_filter=CookieTest.*:-CookieTest.GetCookieManager* --enable-network-service

    There should be no functional change when running without the NetworkService enabled.

    Known issues: - CefCookieManager::SetSupportedSchemes is not yet implemented.

    → <<cset 85c34c4dcf43>>

  15. Marshall Greenblatt

    Move CookieManager callbacks to the UI thread (see issue #2622).

    The Chromium content layer (which also exposes the NetworkService interface) generally runs on the UI thread. Previous use of the IO thread for CookieManager callbacks is an implementation detail of the old network stack that shouldn't be exposed to clients.

    To test: Run ceftests. They should pass as expected.

    → <<cset b949d86c40f8>>

  16. Marshall Greenblatt

    The NetworkService process is created with a command line like:

    "cefclient.exe" --type=utility --field-trial-handle=1392,9640803633774816614,1821756762700023746,131072 --lang=en-US --service-sandbox-type=network --log-file="debug.log" --lang=en-US --log-file="debug.log" --service-request-channel-token=12945594653072301775 --mojo-platform-channel-handle=2056 /prefetch:8

    You can debug the NetworkService by running a CEF-based application with --wait-for-debugger-children=utility and attaching to the appropriate child process. A good place to set a breakpoint is the posting site for UtilityServiceFactory::RunNetworkServiceOnIOThread.

    A ContentUtilityClient::RegisterNetworkBinders method will also be called on startup.

    There does not appear to be a capability for configuring the NetworkService directly from inside that process. Instead, the NetworkService is configured from the browser process using NetworkServiceClient. This object is created via CefContentBrowserClient::CreateNetworkContext and followed by a call to CefContentBrowserClient::OnNetworkServiceCreated, where it can be retrieved using network_service->client(). This interface cannot overridden directly but instead delegates handling to objects returned via callbacks like ContentBrowserClient::CreateLoginDelegate.

  17. Marshall Greenblatt

    We need to call CookieMonster::SetCookieableSchemes in the NetworkProcess after the CookieMonster is created [1] and before CookieMonster::MarkCookieStoreAsInitialized is called for the first time [2]. Simply adding a CookieManager::SetCookieableSchemes method (in cookie_manager.h and cookie_manager.mojom) is not sufficient because URLLoaderFactory::CreateLoaderAndStart will always be called first.

    CookieManagerParams (discussed above) has the following members:

      // Schemes that unconditionally allow cookies from secure origins.
      array<string> secure_origin_cookies_allowed_schemes;
    
      // Schemes that unconditionally allow cookies from the same scheme.
      array<string> matching_scheme_cookies_allowed_schemes;
    
      // Schemes that unconditionally allow third party cookies.
      array<string> third_party_cookies_allowed_schemes;
    

    These are checked via CookieSettings::GetCookieSetting but not currently considered by NetworkContext::ApplyContextParamsToBuilder when creating the CookieMonster (where they could be accessed via params_->cookie_manager_params).

    The best option is probably to add a new value in CookieManagerParams which would be set in ProfileNetworkContextService::CreateNetworkContextParams. On the NetworkService side this value would be passed to CookieMonster::SetCookieableSchemes immediately after the CookieMonster is created in NetworkContext::ApplyContextParamsToBuilder.

    [1] Creation call stack:

    >   net.dll!net::CookieMonster::CookieMonster(scoped_refptr<net::CookieMonster::PersistentCookieStore> store, net::ChannelIDService * channel_id_service, base::TimeDelta last_access_threshold, net::NetLog * net_log) Line 369    C++
        net.dll!net::CookieMonster::CookieMonster(scoped_refptr<net::CookieMonster::PersistentCookieStore> store, net::ChannelIDService * channel_id_service, net::NetLog * net_log) Line 346   C++
        net.dll!net::URLRequestContextBuilder::Build() Line 443 C++
        network_service.dll!network::NetworkContext::ApplyContextParamsToBuilder(network::URLRequestContextBuilderMojo * builder) Line 1973 C++
        network_service.dll!network::NetworkContext::MakeURLRequestContext() Line 2193  C++
        network_service.dll!network::NetworkContext::NetworkContext(network::NetworkService * network_service, mojo::InterfaceRequest<network::mojom::NetworkContext> request, mojo::StructPtr<network::mojom::NetworkContextParams> params, base::OnceCallback<void (network::NetworkContext *)> on_connection_close_callback) Line 535    C++
        [External Code] 
        network_service.dll!network::NetworkService::CreateNetworkContext(mojo::InterfaceRequest<network::mojom::NetworkContext> request, mojo::StructPtr<network::mojom::NetworkContextParams> params) Line 446    C++
        network_service.dll!network::mojom::NetworkServiceStubDispatch::Accept(network::mojom::NetworkService * impl, mojo::Message * message) Line 3872    C++
    

    [2] MarkCookieStoreAsInitialized call stack:

    >   net.dll!net::CookieMonster::MarkCookieStoreAsInitialized() Line 784 C++
        net.dll!net::CookieMonster::DoCookieCallbackForHostOrDomain(base::OnceCallback<void ()> callback, base::BasicStringPiece<std::basic_string<char,std::char_traits<char>,std::allocator<char> > > host_or_domain) Line 1825   C++
        net.dll!net::CookieMonster::DoCookieCallbackForURL(base::OnceCallback<void ()> callback, const GURL & url) Line 1819    C++
        net.dll!net::CookieMonster::GetCookieListWithOptionsAsync(const GURL & url, const net::CookieOptions & options, base::OnceCallback<void (const std::vector<net::CanonicalCookie,std::allocator<net::CanonicalCookie> > &, const std::vector<net::CookieWithStatus,std::allocator<net::CookieWithStatus> > &)> callback) Line 457    C++
        net.dll!net::URLRequestHttpJob::AddCookieHeaderAndStart() Line 705  C++
        net.dll!net::URLRequestHttpJob::Start() Line 442    C++
        net.dll!net::URLRequest::StartJob(net::URLRequestJob * job) Line 698    C++
        net.dll!net::URLRequest::BeforeRequestComplete(int error) Line 638  C++
        net.dll!net::URLRequest::Start() Line 557   C++
        network_service.dll!network::URLLoader::ScheduleStart() Line 531    C++
        network_service.dll!network::URLLoader::URLLoader(net::URLRequestContext * url_request_context, network::mojom::NetworkServiceClient * network_service_client, base::OnceCallback<void (network::mojom::URLLoader *)> delete_callback, mojo::InterfaceRequest<network::mojom::URLLoader> url_loader_request, int options, const network::ResourceRequest & request, mojo::InterfacePtr<network::mojom::URLLoaderClient> url_loader_client, const net::NetworkTrafficAnnotationTag & traffic_annotation, const network::mojom::URLLoaderFactoryParams * factory_params, unsigned int request_id, scoped_refptr<network::ResourceSchedulerClient> resource_scheduler_client, base::WeakPtr<network::KeepaliveStatisticsRecorder> keepalive_statistics_recorder, base::WeakPtr<network::NetworkUsageAccumulator> network_usage_accumulator, network::mojom::TrustedURLLoaderHeaderClient * url_loader_header_client) Line 447  C++
        [External Code] 
        network_service.dll!network::URLLoaderFactory::CreateLoaderAndStart(mojo::InterfaceRequest<network::mojom::URLLoader> request, int routing_id, int request_id, unsigned int options, const network::ResourceRequest & url_request, mojo::InterfacePtr<network::mojom::URLLoaderClient> client, const net::MutableNetworkTrafficAnnotationTag & traffic_annotation) Line 135 C++
        network_service.dll!network::cors::CorsURLLoaderFactory::CreateLoaderAndStart(mojo::InterfaceRequest<network::mojom::URLLoader> request, int routing_id, int request_id, unsigned int options, const network::ResourceRequest & resource_request, mojo::InterfacePtr<network::mojom::URLLoaderClient> client, const net::MutableNetworkTrafficAnnotationTag & traffic_annotation) Line 121  C++
        network_service.dll!network::mojom::URLLoaderFactoryStubDispatch::Accept(network::mojom::URLLoaderFactory * impl, mojo::Message * message) Line 210 C++
    
  18. Mike Wiedenbauer reporter

    @magreenblatt I guess i then just can call CefBrowserContext::GetURLLoaderFactory(), as it seems it's exactly doing what you described i should do?:) I'll create a new class "CefURLLoader" which will be, implementation wise, based on SimpleURLLoader.

  19. Marshall Greenblatt

    Fix crash on shutdown with extensions enabled (see issue #2622).

    We don't support the WebRequestAPI yet, so we shouldn't be creating any objects for it.

    To test: Run cefclient --enable-network-service and then close the app.

    → <<cset 9ce29e8ec5cc>>

  20. Marshall Greenblatt

    Mojo messages related to the NetworkService can be debugged as follows:

    1. Add enable_mojo_tracing=true to GN_DEFINES and rebuild.
    2. Run with the --enable-network-service --trace-startup=mojom command-line flags.
    3. Navigate to chrome://tracing in Google Chrome.
    4. Click the "Load" button and select the chrometrace.log file created by step 2 (this file will be in your current working directory, or out\Debug_GN_x86\obj\cef when running with Visual Studio).

    You'll see a view like this (go here for general information on using the tracing tool): tracing.png

  21. Mike Wiedenbauer reporter

    @magreenblatt I've created the follwing PR: https://bitbucket.org/chromiumembedded/cef/pull-requests/227 It's still work in progress, but i'd appreciate any comments on this, please (so i can implement it in the correct way). It's based on SimpleURLLoader tho. I had to decline (delete) the PR because i rebased my working branch on this to your "cef_spotify/net_service" fork/branch. Now i'd like to create a PR from mine into your fork/branch rather than against the chromimumembedded master. How can i achive this? The reason behind is that if i create against the chromimumembedded master i'd also create a PR for all your changes too, which would be wrong in that case.

  22. Mike Wiedenbauer reporter

    @magreenblatt Starting cefclient (on my branch, created from master) with "--enable-network-service" ends up in an immediate crash :(

    cefclient --enable-network-service
    [0403/115436.863537:FATAL:feature_list.cc(236)] Check failed: !g_initialized_from_accessor. 
    #0 0x7fbfae786c79 base::debug::CollectStackTrace()
    #1 0x7fbfae6ed1f3 base::debug::StackTrace::StackTrace()
    #2 0x7fbfae70132e logging::LogMessage::~LogMessage()
    #3 0x7fbfae6ef268 base::FeatureList::InitializeInstance()
    #4 0x7fbfad1a1f41 content::SetUpFieldTrialsAndFeatureList()
    #5 0x7fbfae3f9e91 content::ContentMainRunnerImpl::RunServiceManager()
    #6 0x7fbfae3f9e06 content::ContentMainRunnerImpl::Run()
    #7 0x7fbfafe95db9 service_manager::MainRun()
    #8 0x7fbfae61bd04 CefContext::Initialize()
    #9 0x7fbfae61b8d3 CefInitialize()
    #10 0x7fbfac5e3430 cef_initialize
    #11 0x558ea8255de1 CefInitialize()
    #12 0x558ea81f4a7a client::MainContextImpl::Initialize()
    #13 0x558ea8227631 main
    #14 0x7fbfa7791b97 __libc_start_main
    #15 0x558ea81dc02a _start
    
    Received signal 6
    #0 0x7fbfae786c79 base::debug::CollectStackTrace()
    #1 0x7fbfae6ed1f3 base::debug::StackTrace::StackTrace()
    #2 0x7fbfae786801 base::debug::(anonymous namespace)::StackDumpSignalHandler()
    #3 0x7fbfa9aa9890 <unknown>
    #4 0x7fbfa77aee97 gsignal
    #5 0x7fbfa77b0801 abort
    #6 0x7fbfae785635 base::debug::BreakDebugger()
    #7 0x7fbfae701571 logging::LogMessage::~LogMessage()
    #8 0x7fbfae6ef268 base::FeatureList::InitializeInstance()
    #9 0x7fbfad1a1f41 content::SetUpFieldTrialsAndFeatureList()
    #10 0x7fbfae3f9e91 content::ContentMainRunnerImpl::RunServiceManager()
    #11 0x7fbfae3f9e06 content::ContentMainRunnerImpl::Run()
    #12 0x7fbfafe95db9 service_manager::MainRun()
    #13 0x7fbfae61bd04 CefContext::Initialize()
    #14 0x7fbfae61b8d3 CefInitialize()
    #15 0x7fbfac5e3430 cef_initialize
    #16 0x558ea8255de1 CefInitialize()
    #17 0x558ea81f4a7a client::MainContextImpl::Initialize()
    #18 0x558ea8227631 main
    #19 0x7fbfa7791b97 __libc_start_main
    #20 0x558ea81dc02a _start
      r8: 0000000000000000  r9: 00007fff2d45eab0 r10: 0000000000000008 r11: 0000000000000246
     r12: 00007fff2d45ed58 r13: 000000000000005c r14: 00007fff2d45f6b8 r15: 00007fff2d45f6b0
      di: 0000000000000002  si: 00007fff2d45eab0  bp: 00007fff2d45ed00  bx: 00001b850e31c000
      dx: 0000000000000000  ax: 0000000000000000  cx: 00007fbfa77aee97  sp: 00007fff2d45eab0
      ip: 00007fbfa77aee97 efl: 0000000000000246 cgf: 002b000000000033 erf: 0000000000000000
     trp: 0000000000000000 msk: 0000000000000000 cr2: 0000000000000000
    [end of stack trace]
    Calling _exit(1). Core file will not be generated.
    

    Built on ubuntu 18.04 LTS

  23. Marshall Greenblatt

    @shagkur I fixed a similar crash in commit 941d53ebfd. You can set breakpoints in FeatureList where g_initialized_from_accessor = true; to find out where the incorrect/too-early call is coming from.

  24. Mike Wiedenbauer reporter

    @magreenblatt I traced the crash down and as far as i can tell it is caused by the call ChromeBrowserProcessStub::Initialize(), in CefContext::Initialize(), which down the line calls base::FeatureList::IsEnabled(). At this point base::FeatureList is not initialized and hence_initialized_from_accessor = true;. Here's a proposed fix for this:

    diff --git a/libcef/browser/context.cc b/libcef/browser/context.cc
    index 56aa7ab9..6f982591 100644
    --- a/libcef/browser/context.cc
    +++ b/libcef/browser/context.cc
    @@ -421,6 +421,11 @@ bool CefContext::Initialize(const CefMainArgs& args,
       if (exit_code >= 0)
         return false;
    
    +  // This is required because ChromeBrowserProcessStub::Initialize as starting it will
    +  // check some feature flags this will cause a CHECK failure later when this
    +  // gets called by some call down the line of service_manager::MainRun.
    +  content::SetUpFieldTrialsAndFeatureList();
    +
       static_cast<ChromeBrowserProcessStub*>(g_browser_process)->Initialize();
    
       if (settings.multi_threaded_message_loop) {
    @@ -428,11 +433,6 @@ bool CefContext::Initialize(const CefMainArgs& args,
             base::WaitableEvent::ResetPolicy::AUTOMATIC,
             base::WaitableEvent::InitialState::NOT_SIGNALED);
    
    -    // This is required because creating a base::Thread as starting it will
    -    // check some feature flags this will cause a CHECK failure later when this
    -    // gets called by some call down the line of service_manager::MainRun.
    -    content::SetUpFieldTrialsAndFeatureList();
    -
         if (!main_delegate_->CreateUIThread(base::BindOnce(
                 [](CefContext* context, base::WaitableEvent* event) {
                   service_manager::MainRun(*context->sm_main_params_);
    

    This fixes the initial crash for me when "--enable-network-service" is passed.

  25. Marshall Greenblatt

    Support for custom intercept-only handling of external protocols via HandleExternalProtocol was added in https://crrev.com/fc21834b89. With this change we should be able to implement custom scheme handlers using a combination of WillCreateURLLoaderFactory for known protocols (http, etc) and HandleExternalProtocol for custom protocols.

  26. Marshall Greenblatt

    Implement NetworkService request interception/handling (see issue #2622).

    Implementation notes: - Chromium change: CookieMonster::SetCookieableSchemes needs to be called immediately after the CookieMonster is created in NetworkContext:: ApplyContextParamsToBuilder. Add a Profile::GetCookieableSchemes method and NetworkContextParams.cookieable_schemes member (set from ProfileNetworkContextService::CreateNetworkContextParams) to support that. - Chromium change: Add a ContentBrowserClient::HandleExternalProtocol variant that exposes additional NetworkService request information. - GetResourceResponseFilter is not yet implemented.

    API changes: - Resource-related callbacks have been moved from CefRequestHandler to a new CefResourceRequestHandler interface which is returned via the GetResourceRequestHandler method. If the CefRequestHandler declines to handle a resource it can optionally be handled by the CefRequestContextHandler, if any, associated with the loading context. - The OnProtocolExecution callback has been moved from CefRequestHandler to CefResourceRequestHandler and will be called if a custom scheme request is unhandled. - Cookie send/save permission callbacks have been moved from CefRequestHandler and CefResourceHandler to CefResourceRequestHandler. - New methods added to CefResourceHandler that better match NetworkService execution sequence expectations. The old methods are now deprecated. - New methods added to CefRequest and CefResponse.

    Known behavior changes with the NetworkService implementation: - Modifying the |new_url| parameter in OnResourceRedirect will no longer result in the method being called an additional time (likely a bug in the old implementation). - Modifying the request URL in OnResourceResponse would previously cause a redirect. This behavior is now deprecated because the NetworkService does not support this functionality when using default network loaders. Temporary support has been added in combination with CefResourceHandler usage only. - Other changes to the request object in OnResourceResponse will now cause the request to be restarted. This means that OnBeforeResourceLoad, etc, will be called an additional time with the new request information. - CefResponse::GetMimeType will now be empty for non-200 responses. - Requests using custom schemes can now be handled via CefResourceRequestHandler with the same callback behavior as builtin schemes. - Redirects of custom scheme requests will now be followed as expected. - Default handling of builtin schemes can now be disabled by setting |disable_default_handling| to true in GetResourceRequestHandler. - Unhandled requests (custom scheme or builtin scheme with default handling disabled) will fail with an CefResponse::GetError value of ERR_UNKNOWN_URL_SCHEME. - The CefSchemeHandlerFactory::Create callback will now include cookie headers.

    To test: - Run cefclient --enable-network-service. All resources should load successfully (this tests the transparent proxy capability). - All tests pass with NetworkService disabled. - The following tests pass with NetworkService enabled: - CookieTest. - FrameTest. (excluding .Nav) - NavigationTest. (excluding .Redirect) - RequestHandlerTest. - RequestContextTest.Basic - RequestContextTest.Popup - RequestTest. - ResourceManagerTest. - ResourceRequestHandlerTest. (excluding .Filter) - SchemeHandlerTest. - StreamResourceHandlerTest.

    → <<cset 8f240861e308>>

  27. Marshall Greenblatt

    Move cookie load/save callbacks to CefCookieAccessFilter (see issue #2622).

    This change allows the NetworkService to handle cookie load/save in cases where cookies will not be filtered (CefResourceRequestHandler::GetCookieAccessFilter returns null) and the request will be handled by the default network loader. This represents a minor performance improvement by reducing the volume of cross- process messaging in the default (no filtering or custom handing) case. Cookie load/save still needs to be routed through the browser process if a filter is returned, or if a CefResourceHandler is used for the request.

    To test: Test expectations are unchanged.

    → <<cset 2ace33f8b757>>

  28. Marshall Greenblatt

    Fix NetworkService load hang with default request handling (see issue #2622).

    This change fixes a load hang when no custom handlers (CefResourceRequestHandler or registered scheme handler) are found for a request.

    To test: Run cefsimple --enable-network-service and all requests load. Test expectations are unchanged.

    → <<cset 8a4f4bff9b73>>

  29. Marshall Greenblatt

    Fix NetworkService startup assertion with multi-threaded message loop (see issue #2622).

    When using multi-threaded message loop mode the PrefService needs to be created on the UI thread.

    To test: Run cefclient --enable-network-service --multi-threaded-message-loop. The application should start successfully.

    → <<cset 4e089766a5d1>>

  30. Marshall Greenblatt

    @shagkur Can you share any process updates on your CefURLRequest implementation? Thanks.

  31. Marshall Greenblatt

    Add NetworkService support for chrome and chrome-devtools schemes (see issue #2622).

    Known behavior changes: - Unsupported chrome hosts no longer redirect to chrome://version.

    To test: All tests pass with NetworkService disabled. WebUITest. and V8Test. tests pass with NetworkService enabled.

    → <<cset 370cc028cbe3>>

  32. Marshall Greenblatt

    Add NetworkService support for extensions and downloads (see issue #2622).

    To test: - All tests pass with NetworkService disabled. DownloadTest., ExtensionTest. and PluginTest.* tests pass with NetworkService enabled. - The PDF extension displays a file, and the download and print buttons work.

    → <<cset 5ce52bd7759d>>

  33. Marshall Greenblatt

    Fix command-line override of the User-Agent product component (see issue #2622).

    When the NetworkService is enabled the U-A string is configured via SystemNetworkContextManager::CreateDefaultNetworkContextParams, which calls chrome_content_browser_client.cc GetUserAgent(). This change modifies the Chrome implementation to match CEF, so that the U-A product component can still be overridden via the --product-version command-line flag.

    To test: Verify that chrome://version, navigator.userAgent (JS executed from DevTools console) and network requests (headers shown in DevTools Network tab) show the expected User-Agent value in the following cases: - Running cefclient --enable-network-service --user-agent="<value>" - Running cefclient --enable-network-service --product-version="<value>"

    → <<cset 4592cba19fc7>>

  34. Marshall Greenblatt

    Fix NetworkService cache directory structure (see issue #2622).

    To test: When running cefclient --cache-path=c:\temp\cache with NetworkService enabled the the cache directory structure should be "C:\temp\cache\Cache" instead of "C:\temp\cache\cache\Cache".

    → <<cset cef882616bec>>

  35. Marshall Greenblatt

    Support disabling of cookie load/save via SetSupportedSchemes (see issue #2622).

    With this change the CefCookieManager::SetSupportedSchemes method can be used to disable all loading and saving of cookies for the associated request context. This matches functionality that was previously available via GetBlockingManager.

    This change also fixes a bug where Set-Cookie headers returned for a request handled via CefSchemeHandlerFactory would be ignored if there was not also a CefResourceRequestHandler returned for the request.

    To test: All CookieTest.* tests pass.

    → <<cset 8b400331c736>>

  36. Marshall Greenblatt

    @shagkur I’m currently working on CefURLRequest support to match existing functionality. Once that initial work is done you’re welcome to contribute further enhancements.

  37. Mike Wiedenbauer reporter

    @magreenblatt This sounds great. Ohh and sorry for not being much responsive lately. I’ve been quite busy with companies work 😞 I also started, a few weeks ago, locally with a CefURLRequest impl based on networkservices. But as i just said, i got stuck with companies work. But i’m happy to improve you work later on. Thanks so much for all your work 🙂

  38. Marshall Greenblatt

    Add NetworkService support for CefURLRequest (see issue #2622).

    Requests created using CefURLRequest::Create are not associated with a browser/frame. When originating from the render process these requests cannot be intercepted and consequently only http(s) and blob requests are supported. To work around this limitation a new CefFrame::CreateURLRequest method has been added that allows the request to be associated with that browser/frame for interception purposes.

    This change also fixes an issue with the NetworkService implementation where redirected requests could result in two parallel requests being sent to the target server.

    To test: URLRequestTest.* tests pass with NetworkService enabled.

    → <<cset ba0e1b5719cc>>

  39. Marshall Greenblatt

    Cancel NetworkService requests when the browser is destroyed (see issue #2622).

    Pending requests that are associated with a browser will be canceled when that browser is destroyed. Pending requests that are not associated with a browser (e.g. created using CefURLRequest::Create), and that use the global context, may still be pending when CefShutdown is called. For this reason the no_debugct_check attribute has been added for CefResourceRequestHandler and CefCookieAccessFilter interfaces.

    To test: Load a YouTube video or other long-loading content in cefclient and close the application. No assertions trigger for leaked CefFrame objects.

    → <<cset 2ea173a254fa>>

  40. Marshall Greenblatt

    Fix NetworkService ServerTest.* failures and test name typo (see issue #2622).

    Always return ERR_NONE and the response body if a CefURLRequest completes successfully, including for non-2xx status codes. This matches the behavior of the old network stack.

    To test: ServerTest.* tests pass with NetworkService enabled.

    → <<cset bddf2a311bf9>>

  41. Marshall Greenblatt

    Add NetworkService support for more CefRequestContext methods (see issue #2622).

    This adds support for the CloseAllConnections and ResolveHost methods.

    To test: RequestContextTest.Close and RequestContextTest.Resolve tests pass with NetworkService enabled.

    → <<cset 99eebd00c447>>

  42. Marshall Greenblatt

    Add NetworkService support for response filtering (see issue #2622).

    To test: ResourceRequestHandlerTest.Filter* tests pass with NetworkService enabled.

    → <<cset 9ddb01387527>>

  43. Marshall Greenblatt

    Enable NetworkService by default (see issue #2622).

    The NetworkService can still be disabled for a limited time by specifying the --disable-features=NetworkService command-line flag.

    → <<cset 6011d45e383c>>

  44. Mike Wiedenbauer reporter

    @Marshall Greenblatt I’m now working on improving/having a look at CefURLRequest and i figured that you now, consequently, make the CefRequest object read-only, when, for instance, it is passed via the CefResourceHandler. Since i’d need to change flags on it to, for example stop-on.-redirect, i need to either make it writable or create a writeable clone of it. Would it be feasible to add a Clone() function to CefRequest, coping over all necessary fields (also keeping the identifier the same)?

    Or having “flags_” and “first_party_for_cookies_”not protected by the read_only_ flag, since, as of documentation, those 2 are only used by CefURLRequest?

  45. Marshall Greenblatt

    @Mike Wiedenbauer If I understand correctly, you are receiving a read-only CefRequest object from another callback, and you want to use that object to start a CefURLRequest? Adding a CefRequest::Clone method sounds reasonable for that use case.

  46. Mike Wiedenbauer reporter

    @Marshall Greenblatt Yes that’s right, and on the clone i’d like to change the flags accordingly. Okay great. I, then, will add such a method to CefRequest on my branch.

    On another topic: I saw one can now create a CefURLRequest from within a CefFrame object, which is great due to the association and also the callback behavior regarding SSL certificate errors for example. The question i’ve now: When i do this from within a CefResourceHandler, how can i identify such a request was issued by CefURLRequest so it leaves to the default execution in GetResourceHandler (i.e. returning nullptr for that case)?

  47. Marshall Greenblatt

    When i do this from within a CefResourceHandler, how can i identify such a request was issued by CefURLRequest so it leaves to the default execution in GetResourceHandler (i.e. returning nullptr for that case)?

    Maybe set a flag (e.g. in_resource_handler_ = true) inside your CefResourceHandler implementation, and then early exit if you receive a recursive call where in_resource_handler_ is already true.

  48. Mike Wiedenbauer reporter

    @magreenblatt Ahh ofcourse. i can “abuse” the flags fleld of the cloned request to check in the recursive call to GetResourceHandler (need to do it that way, since for every real resource request i create a new instance of my resource handler). Thanks for the hint.

  49. Mike Wiedenbauer reporter

    @magreenblatt I’m now trying to get the certificate error handling to work in the new CefURLRequest. First i thought this might be already, sort of solved, by the fact that you now provide a “CreateURLRequest” method on the frame which in turn binds the URLLoaderFactoryGetter to the render frame host. This then raised some hopes in me that the normal execution flow will trigger (like with the GetResourceRequestHandler), in the end, the OnCertificateError of the CefRequestHandler. But this hope has been grounded harshly. 😉

    Anyways. Since i’d like to help to improve, i’d need to know some kind of starting point on this in the context of the use of the renderframehost in CefURLRequest (i.e when created via CefFrame). Perhaps there’s a way to connect to the certificate error handling stuff?

    From the SimpleURLLoader and its base class the URLLoader i couldn’t find any hook for certificate errors. 😞

  50. Mike Wiedenbauer reporter

    @Marshall Greenblatt From the trace it seems the passed ‘routing_id’ is invalid (-2) on call to NetworkServiceClient::OnSSLCertificateError when triggered via a CefURLRequest.

    I guess we’ll need to implement our own “SimpleURLLoader” capable of taking routing_id etc. to be able to properly handle the certificate error case and others where a proper routing_id is needed.

    Or should we just patch SimpleURLLoader? Because everything what’s needed is to pass the routing_id to SimpleURLLoader?

  51. Marshall Greenblatt

    Linux: Fix crash when closing a browser with pending requests (see issue #2622).

    This change fixes an issue where the cancel_callback for a pending request might already have been executed when the OnBrowserDestroyed notification is received.

    → <<cset 281405486380>>

  52. Marshall Greenblatt

    Fix issues with request callbacks during browser shutdown (see issue #2622).

    The behavior has changed as follows with NetworkService enabled: - All pending and in-progress requests will now be aborted when the CEF context or associated browser is destroyed. The OnResourceLoadComplete callback will now also be called in this case for in-progress requests that have a handler. - The CefResourceHandler::Cancel method will now always be called when resource handling is complete, irrespective of whether handling completed successfully. - Request callbacks that arrive after the OnBeforeClose callback for the associated browser (which may happen for in-progress requests that are aborted on browser destruction) will now always have a non-nullptr CefBrowser parameter. - Allow empty parameters to CefRequest and CefResponse methods where it makes sense (e.g. resetting default response state, or clearing a referrer value). - Fixed a reference loop that was keeping CefResourceHandler objects from being destroyed if they were holding a callback reference (from ProcessRequest, ReadResponse, etc.) during CEF context or associated browser destruction. - Fixed an issue where the main frame was not detached on browser destruction which could cause a crash due to RFH use-after-free (see issue #2498).

    To test: All unit tests pass as expected.

    → <<cset fa5268fa2d87>>

  53. Mike Wiedenbauer reporter

    @Marshall Greenblatt Update to my analysis: It’s probably not necessary to implement our own “SimpleURLLoader”. It seems, it’s just necessary to set “ResourceRequest::render_frame_id” to the routing ID of the render view host. Doing so will trigger the SSL certificate error handler, for instance (as well as probably others attached to this routing id). What i’m not sure about, is if it’s correct to pass ‘0’, like SimpleURLLoader does, to URLLoaderFactory::CreateLoaderAndStart, because the original request seem to pass its RVH routing id.Although my tests have shown that it seem to be enough just to set forementioned render_frame_id member properly.

    What’s your thoughts on this?

    Just to let you know: CefResourceHandler::Open isn’t called on IO thread (got a crash when i tried to create a CefRequest object in this method, needed to post it as a task onto the IO thread)

    PS: The corresponding PR → https://bitbucket.org/chromiumembedded/cef/pull-requests/238

  54. Marshall Greenblatt

    Fix crash in ProxyURLLoaderFactory::MaybeDestroySelf (see issue #2622).

    This is a speculative fix for a crash where |on_disconnect_| appears to be null in ProxyURLLoaderFactory::MaybeDestroySelf. The hypothesis here is that OnURLLoaderClientError is being called while the proxy object is still in-flight to ResourceContextData::AddProxy (e.g. before SetDisconnectCallback has been called for the proxy object). Additonally, this change protects against MaybeDestroySelf attempting to execute |on_disconnect_| multiple times.

    → <<cset 81064faac346>>

  55. Marshall Greenblatt

    Fix crash in ProxyURLLoaderFactory::MaybeDestroySelf (see issue #2622).

    This is a speculative fix for a crash where |on_disconnect_| appears to be null in ProxyURLLoaderFactory::MaybeDestroySelf. The hypothesis here is that OnURLLoaderClientError is being called while the proxy object is still in-flight to ResourceContextData::AddProxy (e.g. before SetDisconnectCallback has been called for the proxy object). Additonally, this change protects against MaybeDestroySelf attempting to execute |on_disconnect_| multiple times.

    → <<cset 19229b6d3867>>

  56. Marshall Greenblatt

    Call stack for the ProxyURLLoaderFactory::MaybeDestroySelf crash mentioned above (from CEF version 75.0.6+g90ecd35+chromium-75.0.3770.80):

    [ 00 ] net_service::ProxyURLLoaderFactory::MaybeDestroySelf()                                                                                                                                                                                                                                                                                                                       ( proxy_url_loader_factory.cc:1183 )
    [ 01 ] net_service::ProxyURLLoaderFactory::RemoveRequest(net_service::InterceptedRequest *)                                                                                                                                                                                                                                                                                         ( proxy_url_loader_factory.cc:1173 )
    [ 02 ] net_service::InterceptedRequest::CallOnComplete(network::URLLoaderCompletionStatus const &,bool)                                                                                                                                                                                                                                                                             ( proxy_url_loader_factory.cc:933 )
    [ 03 ] net_service::InterceptedRequest::OnURLLoaderClientError()                                                                                                                                                                                                                                                                                                                    ( proxy_url_loader_factory.cc:889 )
    [ 04 ] mojo::InterfaceEndpointClient::NotifyError(base::Optional<mojo::DisconnectReason> const &)                                                                                                                                                                                                                                                                                   ( interface_endpoint_client.cc:336 )
    [ 05 ] mojo::internal::MultiplexRouter::ProcessNotifyErrorTask(mojo::internal::MultiplexRouter::Task *,mojo::internal::MultiplexRouter::ClientCallBehavior,base::SequencedTaskRunner *)                                                                                                                                                                                             ( multiplex_router.cc:793 )
    [ 06 ] mojo::internal::MultiplexRouter::ProcessTasks(mojo::internal::MultiplexRouter::ClientCallBehavior,base::SequencedTaskRunner *)                                                                                                                                                                                                                                               ( multiplex_router.cc:704 )
    [ 07 ] mojo::internal::MultiplexRouter::OnPipeConnectionError(bool)                                                                                                                                                                                                                                                                                                                 ( multiplex_router.cc:678 )
    [ 08 ] base::internal::Invoker<base::internal::BindState<void (media::AudioOutputController::*)(bool) __attribute__((thiscall)),scoped_refptr<media::AudioOutputController>,bool>,void ()>::RunOnce                                                                                                                                                                                 ( bind_internal.h:641 )
    [ 09 ] mojo::Connector::HandleError(bool,bool)                                                                                                                                                                                                                                                                                                                                      ( connector.cc:674 )
    [ 10 ] mojo::Connector::OnHandleReadyInternal(unsigned int)                                                                                                                                                                                                                                                                                                                         ( connector.cc:0 )
    [ 11 ] base::internal::Invoker<base::internal::BindState<void (network::mojom::CookieManager_DeleteCookies_ProxyToResponder::*)(unsigned int) __attribute__((thiscall)),std::__1::unique_ptr<network::mojom::CookieManager_DeleteCookies_ProxyToResponder,std::__1::default_delete<network::mojom::CookieManager_DeleteCookies_ProxyToResponder> > >,void (unsigned int)>::RunOnce  ( bind_internal.h:641 )
    [ 12 ] mojo::SimpleWatcher::DiscardReadyState(base::RepeatingCallback<void > const &,unsigned int,mojo::HandleSignalsState const &)                                                                                                                                                                                                                                                 ( simple_watcher.h:194 )
    [ 13 ] base::internal::Invoker<base::internal::BindState<void (*)(const base::RepeatingCallback<void (unsigned int)> &, unsigned int, const mojo::HandleSignalsState &),base::RepeatingCallback<void (unsigned int)> >,void (unsigned int, const mojo::HandleSignalsState &)>::Run                                                                                                  ( bind_internal.h:654 )
    [ 14 ] mojo::SimpleWatcher::OnHandleReady(int,unsigned int,mojo::HandleSignalsState const &)                                                                                                                                                                                                                                                                                        ( simple_watcher.cc:293 )
    [ 15 ] base::internal::Invoker<base::internal::BindState<void (mojo::SimpleWatcher::*)(int, unsigned int, const mojo::HandleSignalsState &) __attribute__((thiscall)),base::WeakPtr<mojo::SimpleWatcher>,int,unsigned int,mojo::HandleSignalsState>,void ()>::RunOnce                                                                                                               ( bind_internal.h:641 )
    [ 16 ] base::TaskAnnotator::RunTask(char const *,base::PendingTask *)                                                                                                                                                                                                                                                                                                               ( task_annotator.cc:114 )
    [ 17 ] base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::sequence_manager::LazyNow *,bool *)                                                                                                                                                                                                                                                  ( thread_controller_with_message_pump_impl.cc:363 )
    [ 18 ] base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoSomeWork()                                                                                                                                                                                                                                                                                          ( thread_controller_with_message_pump_impl.cc:213 )
    [ 19 ] base::MessagePumpForIO::DoRunLoop()                                                                                                                                                                                                                                                                                                                                          ( message_pump_win.cc:631 )
    [ 20 ] base::MessagePumpWin::Run(base::MessagePump::Delegate *)                                                                                                                                                                                                                                                                                                                     ( message_pump_win.cc:75 )
    [ 21 ] base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool,base::TimeDelta)                                                                                                                                                                                                                                                                             ( thread_controller_with_message_pump_impl.cc:448 )
    [ 22 ] base::RunLoop::RunWithTimeout(base::TimeDelta)                                                                                                                                                                                                                                                                                                                               ( run_loop.cc:161 )
    [ 23 ] base::RunLoop::Run()                                                                                                                                                                                                                                                                                                                                                         ( run_loop.cc:129 )
    [ 24 ] base::Thread::Run(base::RunLoop *)                                                                                                                                                                                                                                                                                                                                           ( thread.cc:242 )
    [ 25 ] content::BrowserProcessSubThread::IOThreadRun(base::RunLoop *)                                                                                                                                                                                                                                                                                                               ( browser_process_sub_thread.cc:176 )
    [ 26 ] base::Thread::ThreadMain()                                                                                                                                                                                                                                                                                                                                                   ( thread.cc:312 )
    [ 27 ] base::`anonymous namespace'::ThreadFunc                                                                                                                                                                                                                                                                                                                                      ( platform_thread_win.cc:97 )
    
  57. Marshall Greenblatt

    Fix crashes when a request is aborted during initialization (see issue #2622).

    Initialization of request objects requires asynchronous hops between the UI and IO threads. In some cases the browser may be destroyed, the mojo connection may be aborted, or the ProxyURLLoaderFactory object may be deleted while initialization is still in progress. This change fixes crashes and adds unit tests that try to reproduce these conditions.

    To test: Run ceftests --gtest_repeat=50 --gtest_filter=ResourceRequestHandlerTest.Basic*Abort*

    → <<cset ba08c21517df>>

  58. Marshall Greenblatt

    Fix crashes when a request is aborted during initialization (see issue #2622).

    Initialization of request objects requires asynchronous hops between the UI and IO threads. In some cases the browser may be destroyed, the mojo connection may be aborted, or the ProxyURLLoaderFactory object may be deleted while initialization is still in progress. This change fixes crashes and adds unit tests that try to reproduce these conditions.

    To test: Run ceftests --gtest_repeat=50 --gtest_filter=ResourceRequestHandlerTest.Basic*Abort*

    → <<cset 5da93a11c877>>

  59. Marshall Greenblatt

    Fix crash if a pending request is continued after deletion (see issue #2622).

    This is a speculative fix for a crash where the pending ResourceRequest appears to be invalid after the request is continued from SetInitialized.

    → <<cset b03a419c6b49>>

  60. Marshall Greenblatt

    Fix crash if a pending request is continued after deletion (see issue #2622).

    This is a speculative fix for a crash where the pending ResourceRequest appears to be invalid after the request is continued from SetInitialized.

    → <<cset 6ad1dea9fa95>>

  61. Marshall Greenblatt

    Call stack for the ResourceRequest crash mentioned above (from CEF version 75.0.8+g5da93a1+chromium-75.0.3770.80):

    Unhandled exception at 0x6FF96B1B (libcef.dll) in 1b8ce3d7.dmp: 0xC0000005: Access violation reading location 0xE8287E89.
    
    >   libcef.dll!base::EqualsCaseInsensitiveASCII(base::BasicStringPiece<std::__1::basic_string<char> > a, base::BasicStringPiece<std::__1::basic_string<char> > b) Line 213  C++
        libcef.dll!net::HttpRequestHeaders::FindHeader(const base::BasicStringPiece<std::__1::basic_string<char> > & key) Line 216  C++
        libcef.dll!net::HttpRequestHeaders::SetHeaderIfMissing(const base::BasicStringPiece<std::__1::basic_string<char> > & key, const base::BasicStringPiece<std::__1::basic_string<char> > & value) Line 113 C++
        libcef.dll!net_service::`anonymous namespace'::InterceptedRequestHandlerWrapper::OnBeforeRequest(const net_service::RequestId & id, network::ResourceRequest * request, bool request_was_redirected, base::OnceCallback<void (bool, bool)> callback, base::OnceCallback<void (int)> cancel_callback) Line 414   C++
        libcef.dll!net_service::`anonymous namespace'::InterceptedRequestHandlerWrapper::PendingRequest::Run(net_service::`anonymous namespace'::InterceptedRequestHandlerWrapper * self) Line 153  C++
        libcef.dll!net_service::`anonymous namespace'::InterceptedRequestHandlerWrapper::SetInitialized(std::__1::unique_ptr<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitState,std::__1::default_delete<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitState> > init_state) Line 382   C++
        libcef.dll!net_service::`anonymous namespace'::InterceptedRequestHandlerWrapper::InitHelper::SetInitialized(std::__1::unique_ptr<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitState,std::__1::default_delete<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitState> > init_state) Line 333   C++
        libcef.dll!base::internal::FunctorTraits<void (history::(anonymous namespace)::RequestImpl::*)(std::__1::unique_ptr<std::__1::basic_string<char>,std::__1::default_delete<std::__1::basic_string<char> > >) __attribute__((thiscall)),void>::Invoke<void (history::(anonymous namespace)::RequestImpl::*)(std::__1::unique_ptr<std::__1::basic_string<char>,std::__1::default_delete<std::__1::basic_string<char> > >) __attribute__((thiscall)),history::(anonymous namespace)::RequestImpl *,std::__1::unique_ptr<std::__1::basic_string<char>,std::__1::default_delete<std::__1::basic_string<char> > > >(void(history::`anonymous namespace'::RequestImpl::*)(std::__1::unique_ptr<std::__1::basic_string<char>,std::__1::default_delete<std::__1::basic_string<char> > >) receiver_ptr, history::`anonymous namespace'::RequestImpl * && args, std::__1::unique_ptr<std::__1::basic_string<char>,std::__1::default_delete<std::__1::basic_string<char> > > &&) Line 499    C++
        libcef.dll!base::internal::Invoker<base::internal::BindState<void (net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitHelper::*)(std::__1::unique_ptr<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitState,std::__1::default_delete<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitState> >) __attribute__((thiscall)),scoped_refptr<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitHelper>,std::__1::unique_ptr<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitState,std::__1::default_delete<net_service::(anonymous namespace)::InterceptedRequestHandlerWrapper::InitState> > >,void ()>::RunOnce(base::internal::BindStateBase * base) Line 641 C++
        libcef.dll!base::TaskAnnotator::RunTask(const char * trace_event_name, base::PendingTask * pending_task) Line 114   C++
        libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::sequence_manager::LazyNow * continuation_lazy_now, bool * ran_task) Line 364 C++
        libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoSomeWork() Line 216 C++
        libcef.dll!base::MessagePumpForIO::DoRunLoop() Line 633 C++
        libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) Line 77    C++
        libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed, base::TimeDelta timeout) Line 448 C++
        libcef.dll!base::RunLoop::RunWithTimeout(base::TimeDelta timeout) Line 161  C++
        libcef.dll!base::RunLoop::Run() Line 130    C++
        libcef.dll!base::Thread::Run(base::RunLoop * run_loop) Line 243 C++
        libcef.dll!content::BrowserProcessSubThread::IOThreadRun(base::RunLoop * run_loop) Line 177 C++
        libcef.dll!base::Thread::ThreadMain() Line 315  C++
        libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params) Line 100  C++
    
  62. Marshall Greenblatt

    Fix loading of http(s) sub-resources from custom scheme initiator (fixes issue #2685, see issue #2622).

    Determine external request status based on the current URL instead of the request initiator.

    → <<cset 02a6b3bb388f>>

  63. Marshall Greenblatt

    Fix loading of http(s) sub-resources from custom scheme initiator (fixes issue #2685, see issue #2622).

    Determine external request status based on the current URL instead of the request initiator.

    → <<cset d792e5fddf6e>>

  64. Marshall Greenblatt

    Fix cross-origin redirect from OnBeforeResourceLoad (fixes issue #2695, see issue #2622).

    Modifying the URL in OnBeforeResourceLoad causes an internal redirect response. In cases where the request is cross-origin (containing a non-null "Origin" header) the redirect response must include the "Access-Control-Allow-Origin" header, otherwise the request will be blocked.

    This change also fixes a problem where existing request headers would be discarded if the request was modified in OnBeforeResourceLoad.

    → <<cset 45329d05a5e0>>

  65. Marshall Greenblatt

    Fix cross-origin redirect from OnBeforeResourceLoad (fixes issue #2695, see issue #2622).

    Modifying the URL in OnBeforeResourceLoad causes an internal redirect response. In cases where the request is cross-origin (containing a non-null "Origin" header) the redirect response must include the "Access-Control-Allow-Origin" header, otherwise the request will be blocked.

    This change also fixes a problem where existing request headers would be discarded if the request was modified in OnBeforeResourceLoad.

    → <<cset 2c92fcd3cdf1>>

  66. Marshall Greenblatt

    Remove POST data after redirect to GET (see issue #2707, see issue #2622).

    For 303 redirects all request methods except HEAD are converted to GET as per the latest http draft. For historical reasons the draft also allows POST requests to be converted to GETs when following 301/302 redirects. Most major browsers do this and so shall we. When a request is converted to GET any POST data should also be removed.

    Use 307 redirects instead if you want the request to be repeated using the same method and POST data.

    → <<cset 3b211d4bf503>>

  67. Marshall Greenblatt

    Remove POST data after redirect to GET (see issue #2707, see issue #2622).

    For 303 redirects all request methods except HEAD are converted to GET as per the latest http draft. For historical reasons the draft also allows POST requests to be converted to GETs when following 301/302 redirects. Most major browsers do this and so shall we. When a request is converted to GET any POST data should also be removed.

    Use 307 redirects instead if you want the request to be repeated using the same method and POST data.

    → <<cset 5892ffc38291>>

  68. Marshall Greenblatt

    Add support for GetAuthCredentials (fixes issue #2718, see issue #2622).

    When NetworkService is enabled requests created using CefFrame::CreateURLRequest will call CefRequestHandler::GetAuthCredentials for the associated browser after calling CefURLRequestClient::GetAuthCredentials if that call returns false.

    → <<cset 5e9ca096e0bb>>

  69. Marshall Greenblatt

    Add support for GetAuthCredentials (fixes issue #2718, see issue #2622).

    When NetworkService is enabled requests created using CefFrame::CreateURLRequest will call CefRequestHandler::GetAuthCredentials for the associated browser after calling CefURLRequestClient::GetAuthCredentials if that call returns false.

    → <<cset 3f1ebebde5c8>>

  70. Marshall Greenblatt

    Fix redirect of requests with credentials mode 'include' (fixes issue #2699, see issue #2622).

    Modifying the URL in OnBeforeResourceLoad causes an internal redirect response. In cases where the request is cross-origin and credentials mode is 'include' the redirect response must include the "Access-Control-Allow-Credentials" header, otherwise the request will be blocked.

    → <<cset 849a6e64dc7d>>

  71. Marshall Greenblatt

    Fix redirect of requests with credentials mode 'include' (fixes issue #2699, see issue #2622).

    Modifying the URL in OnBeforeResourceLoad causes an internal redirect response. In cases where the request is cross-origin and credentials mode is 'include' the redirect response must include the "Access-Control-Allow-Credentials" header, otherwise the request will be blocked.

    → <<cset 99c27f57b171>>

  72. Marshall Greenblatt

    Fix crash on shutdown with PDF viewer and multi-threaded message loop (fixes issue #2709, see issue #2622)

    Requests from the PDF viewer are not associated with a CefBrowser. Consequently, the InterceptedRequestHandler for those requests will register as an observer of CefContext destruction. When the browser is closed the InterceptedRequestHandler is destroyed and an async task is posted to remove/delete the observer on the UI thread. If CefShutdown is then called the task may execute after shutdown has started, in which case CONTEXT_STATE_VALID() will return false. We still need to remove the observer in this case to avoid a use-after-free in FinishShutdownOnUIThread.

    → <<cset e57acace0b23>>

  73. Marshall Greenblatt

    Fix crash on shutdown with PDF viewer and multi-threaded message loop (fixes issue #2709, see issue #2622)

    Requests from the PDF viewer are not associated with a CefBrowser. Consequently, the InterceptedRequestHandler for those requests will register as an observer of CefContext destruction. When the browser is closed the InterceptedRequestHandler is destroyed and an async task is posted to remove/delete the observer on the UI thread. If CefShutdown is then called the task may execute after shutdown has started, in which case CONTEXT_STATE_VALID() will return false. We still need to remove the observer in this case to avoid a use-after-free in FinishShutdownOnUIThread.

    → <<cset 6223f1bcb4aa>>

  74. Marshall Greenblatt

    Fix crash on shutdown with PDF viewer and multi-threaded message loop (fixes issue #2709, see issue #2622)

    Requests from the PDF viewer are not associated with a CefBrowser. Consequently, the InterceptedRequestHandler for those requests will register as an observer of CefContext destruction. When the browser is closed the InterceptedRequestHandler is destroyed and an async task is posted to remove/delete the observer on the UI thread. If CefShutdown is then called the task may execute after shutdown has started, in which case CONTEXT_STATE_VALID() will return false. We still need to remove the observer in this case to avoid a use-after-free in FinishShutdownOnUIThread.

    → <<cset b34af23449c0>>

  75. Czarek Tomczak

    I am running latest CEF on Linux (76.1.10+g20d771a+chromium-76.0.3809.87) and when app closes seeing these errors in logs only when NetworkService is enabled:

    [ERROR:browser_process_sub_thread.cc(203)] Waited 1 ms for network service
    [ERROR:process_posix.cc(330)] Unable to terminate process 9115: No such process (3)
    

    Additionally when I enable CefSettings.multi_threaded_message_loop and also only with NetworkService enabled I am seeing more errors when app closes, it is either this error:

    [FATAL:lock_impl_posix.cc(103)] Check failed: rv == 0 (22 vs. 0). Invalid argument. Hint: This is often related to a use-after-free.
    Process finished with exit code 133 (interrupted by signal 5: SIGTRAP)
    

    Or this:

    ../nptl/pthread_mutex_lock.c:350: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
    Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
    

    When I disable NetworkService using the --disable-features=NetworkService switch then none of these errors appear anymore.

  76. Marshall Greenblatt

    [ERROR:browser_process_sub_thread.cc(203)] Waited 1 ms for network service

    This message is expected behavior.

    Additionally when I enable CefSettings.multi_threaded_message_loop and also only with NetworkService enabled I am seeing more errors when app closes,

    Can you post the symbolized call stacks for these assertions?

  77. Czarek Tomczak

    @Marshall Greenblatt Below is the stack trace you’ve requested. CEF version 76.1.10+g20d771a+chromium-76.0.3809.87.

    [0903/175714.071779:FATAL:lock_impl_posix.cc(103)] Check failed: rv == 0 (22 vs. 0). Invalid 
    argument. Hint: This is often related to a use-after-free.
    
    Program received signal SIGTRAP, Trace/breakpoint trap.
    [Switching to Thread 0x7fffe2a60700 (LWP 14094)]
    0x00007ffff233cc4e in operator() () at ../../base/logging.cc:937
    937 ../../base/logging.cc: No such file or directory.
    (gdb) bt
    #0  0x00007ffff233cc4e in operator() () at ../../base/logging.cc:937
    #1  ~LogMessage () at ../../base/logging.cc:937
    #2  0x00007ffff2408a8c in Lock () at ../../base/synchronization/lock_impl_posix.cc:103
    #3  0x00007ffff236ee1e in Acquire () at ../../base/synchronization/lock.h:50
    #4  BasicAutoLock () at ../../base/synchronization/lock_impl.h:84
    #5  CalledOnValidSequence () at ../../base/sequence_checker_impl.cc:40
    #6  0x00007ffff36dffac in GetBoolean () at ../../components/prefs/pref_service.cc:154
    #7  0x00007ffff4230c09 in CreateDefaultNetworkContextParams ()
        at ../../chrome/browser/net/system_network_context_manager.cc:679
    #8  0x00007ffff4225c8e in CreateNetworkContextParams ()
        at ../../chrome/browser/net/profile_network_context_service.cc:376
    #9  0x00007ffff4225773 in CreateNetworkContext ()
        at ../../chrome/browser/net/profile_network_context_service.cc:157
    #10 0x00007ffff42e166c in Profile::CreateNetworkContext(bool, base::FilePath const&) ()
        at ../../chrome/browser/profiles/profile.cc:267
    #11 0x00007ffff21c23f1 in CefContentBrowserClient::CreateNetworkContext(content::BrowserContext*, bool, base::FilePath const&) () at ../../cef/libcef/browser/content_browser_client.cc:1352
    #12 0x00007ffff0362d2a in InitNetworkContext ()
        at ../../content/browser/storage_partition_impl.cc:1459
    #13 0x00007fffef05f974 in Invoke<void (net::HostResolverManager::ProcTask::*)(), base::WeakPtr<net::HostResolverManager::ProcTask>> () at ../../base/bind_internal.h:499
    #14 MakeItSo<void (net::HostResolverManager::ProcTask::*)(), base::WeakPtr<net::HostResolverManager::ProcTask>> () at ../../base/bind_internal.h:619
    #15 RunImpl<void (net::HostResolverManager::ProcTask::*)(), std::__1::tuple<base::WeakPtr<net::HostResolverManager::ProcTask> >, 0> () at ../../base/bind_internal.h:672
    #16 RunOnce () at ../../base/bind_internal.h:641
    #17 0x00007ffff24f97f0 in Run () at ../../base/callback.h:97
    #18 NotifyError () at ../../mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:340
    #19 0x00007ffff24ffff3 in ProcessNotifyErrorTask ()
    ---Type <return> to continue, or q <return> to quit---
        at ../../mojo/public/cpp/bindings/lib/multiplex_router.cc:793
    #20 0x00007ffff24fd0de in ProcessTasks ()
        at ../../mojo/public/cpp/bindings/lib/multiplex_router.cc:706
    #21 0x00007ffff250049f in LockAndCallProcessTasks ()
        at ../../mojo/public/cpp/bindings/lib/multiplex_router.cc:901
    #22 0x00007fffef06c85b in Invoke<void (net::SerialWorker::*)(), scoped_refptr<net::SerialWorker>>
        () at ../../base/bind_internal.h:499
    #23 MakeItSo<void (net::SerialWorker::*)(), scoped_refptr<net::SerialWorker> > ()
        at ../../base/bind_internal.h:599
    #24 RunImpl<void (net::SerialWorker::*)(), std::__1::tuple<scoped_refptr<net::SerialWorker> >, 0>
        () at ../../base/bind_internal.h:672
    #25 RunOnce () at ../../base/bind_internal.h:641
    #26 0x00007ffff2386328 in Run () at ../../base/callback.h:97
    #27 RunTask () at ../../base/task/common/task_annotator.cc:142
    #28 0x00007ffff23a2681 in DoWorkImpl ()
        at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:368
    #29 0x00007ffff23a2095 in DoSomeWork ()
        at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:219
    #30 0x00007ffff2345586 in Run () at ../../base/message_loop/message_pump_glib.cc:290
    #31 0x00007ffff23a33e7 in Run ()
        at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:466
    #32 0x00007ffff236a12d in RunWithTimeout () at ../../base/run_loop.cc:161
    #33 0x00007ffff229cefe in ThreadMain () at ../../cef/libcef/common/main_delegate.cc:349
    #34 0x00007ffff240da88 in ThreadFunc () at ../../base/threading/platform_thread_posix.cc:81
    #35 0x00007fffecb9b184 in start_thread (arg=0x7fffe2a60700) at pthread_create.c:312
    #36 0x00007fffec8c803d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
    

    This FATAL error occurs only sometimes and when it doesn’t occur I can see numerous strange messages like for example this:

    Program received signal SIGABRT, Aborted.
    [Switching to Thread 0x7fffe2a60700 (LWP 14701)]
    0x00007fffec800c37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
    56  ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
    (gdb) bt
    #0  0x00007fffec800c37 in __GI_raise (sig=sig@entry=6)
        at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
    #1  0x00007fffec804028 in __GI_abort () at abort.c:89
    #2  0x00007fffec7f9bf6 in __assert_fail_base (
        fmt=0x7fffec94e058 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
        assertion=assertion@entry=0x7fffecba5a3c "mutex->__data.__owner == 0", 
        file=file@entry=0x7fffecba5a08 "../nptl/pthread_mutex_lock.c", line=line@entry=116, 
        function=function@entry=0x7fffecba5b40 <__PRETTY_FUNCTION__.8524> "__pthread_mutex_lock")
        at assert.c:92
    #3  0x00007fffec7f9ca2 in __GI___assert_fail (
        assertion=0x7fffecba5a3c "mutex->__data.__owner == 0", 
        file=0x7fffecba5a08 "../nptl/pthread_mutex_lock.c", line=116, 
        function=0x7fffecba5b40 <__PRETTY_FUNCTION__.8524> "__pthread_mutex_lock") at assert.c:101
    #4  0x00007fffecb9d51b in __GI___pthread_mutex_lock (mutex=0xfefefefefefefeff)
        at ../nptl/pthread_mutex_lock.c:116
    #5  0x00007ffff24089c2 in Lock () at ../../base/synchronization/lock_impl_posix.cc:102
    #6  0x00007ffff236ee1e in Acquire () at ../../base/synchronization/lock.h:50
    #7  BasicAutoLock () at ../../base/synchronization/lock_impl.h:84
    #8  CalledOnValidSequence () at ../../base/sequence_checker_impl.cc:40
    #9  0x00007ffff36dffac in GetBoolean () at ../../components/prefs/pref_service.cc:154
    #10 0x00007ffff4230c09 in CreateDefaultNetworkContextParams ()
        at ../../chrome/browser/net/system_network_context_manager.cc:679
    #11 0x00007ffff4225c8e in CreateNetworkContextParams ()
        at ../../chrome/browser/net/profile_network_context_service.cc:376
    #12 0x00007ffff4225773 in CreateNetworkContext ()
        at ../../chrome/browser/net/profile_network_context_service.cc:157
    #13 0x00007ffff42e166c in Profile::CreateNetworkContext(bool, base::FilePath const&) ()
        at ../../chrome/browser/profiles/profile.cc:267
    #14 0x00007ffff21c23f1 in CefContentBrowserClient::CreateNetworkContext(content::BrowserContext*, bo---Type <return> to continue, or q <return> to quit---
    ol, base::FilePath const&) () at ../../cef/libcef/browser/content_browser_client.cc:1352
    #15 0x00007ffff0362d2a in InitNetworkContext ()
        at ../../content/browser/storage_partition_impl.cc:1459
    #16 0x00007fffef05f974 in Invoke<void (net::HostResolverManager::ProcTask::*)(), base::WeakPtr<net::HostResolverManager::ProcTask>> () at ../../base/bind_internal.h:499
    #17 MakeItSo<void (net::HostResolverManager::ProcTask::*)(), base::WeakPtr<net::HostResolverManager::ProcTask>> () at ../../base/bind_internal.h:619
    #18 RunImpl<void (net::HostResolverManager::ProcTask::*)(), std::__1::tuple<base::WeakPtr<net::HostResolverManager::ProcTask> >, 0> () at ../../base/bind_internal.h:672
    #19 RunOnce () at ../../base/bind_internal.h:641
    #20 0x00007ffff24f97f0 in Run () at ../../base/callback.h:97
    #21 NotifyError () at ../../mojo/public/cpp/bindings/lib/interface_endpoint_client.cc:340
    #22 0x00007ffff24ffff3 in ProcessNotifyErrorTask ()
        at ../../mojo/public/cpp/bindings/lib/multiplex_router.cc:793
    #23 0x00007ffff24fd0de in ProcessTasks ()
        at ../../mojo/public/cpp/bindings/lib/multiplex_router.cc:706
    #24 0x00007ffff250049f in LockAndCallProcessTasks ()
        at ../../mojo/public/cpp/bindings/lib/multiplex_router.cc:901
    #25 0x00007fffef06c85b in Invoke<void (net::SerialWorker::*)(), scoped_refptr<net::SerialWorker>>
        () at ../../base/bind_internal.h:499
    #26 MakeItSo<void (net::SerialWorker::*)(), scoped_refptr<net::SerialWorker> > ()
        at ../../base/bind_internal.h:599
    #27 RunImpl<void (net::SerialWorker::*)(), std::__1::tuple<scoped_refptr<net::SerialWorker> >, 0>
        () at ../../base/bind_internal.h:672
    #28 RunOnce () at ../../base/bind_internal.h:641
    #29 0x00007ffff2386328 in Run () at ../../base/callback.h:97
    #30 RunTask () at ../../base/task/common/task_annotator.cc:142
    #31 0x00007ffff23a2681 in DoWorkImpl ()
        at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:368
    ---Type <return> to continue, or q <return> to quit---
    #32 0x00007ffff23a2095 in DoSomeWork ()
        at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:219
    #33 0x00007ffff2345817 in HandleDispatch () at ../../base/message_loop/message_pump_glib.cc:256
    #34 WorkSourceDispatch () at ../../base/message_loop/message_pump_glib.cc:108
    #35 0x00007fffed0fde14 in g_main_dispatch (context=0x7fffd400ae30)
        at /build/glib2.0-WFyp2b/glib2.0-2.40.2/./glib/gmain.c:3064
    #36 g_main_context_dispatch (context=context@entry=0x7fffd400ae30)
        at /build/glib2.0-WFyp2b/glib2.0-2.40.2/./glib/gmain.c:3663
    #37 0x00007fffed0fe058 in g_main_context_iterate (context=context@entry=0x7fffd400ae30, 
        block=block@entry=0, dispatch=dispatch@entry=1, self=<optimized out>)
        at /build/glib2.0-WFyp2b/glib2.0-2.40.2/./glib/gmain.c:3734
    #38 0x00007fffed0fe0fc in g_main_context_iteration (context=0x7fffd400ae30, may_block=0)
        at /build/glib2.0-WFyp2b/glib2.0-2.40.2/./glib/gmain.c:3795
    #39 0x00007ffff234556e in Run () at ../../base/message_loop/message_pump_glib.cc:286
    #40 0x00007ffff23a33e7 in Run ()
        at ../../base/task/sequence_manager/thread_controller_with_message_pump_impl.cc:466
    #41 0x00007ffff236a12d in RunWithTimeout () at ../../base/run_loop.cc:161
    #42 0x00007ffff229cefe in ThreadMain () at ../../cef/libcef/common/main_delegate.cc:349
    #43 0x00007ffff240da88 in ThreadFunc () at ../../base/threading/platform_thread_posix.cc:81
    #44 0x00007fffecb9b184 in start_thread (arg=0x7fffe2a60700) at pthread_create.c:312
    #45 0x00007fffec8c803d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
    

    Or this:

    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread 0x7fffe2a60700 (LWP 14382)]
    _int_malloc (av=0x7fffd4000020, bytes=96) at malloc.c:3391
    3391    malloc.c: No such file or directory.
    

    Or:

    Program received signal SIGILL, Illegal instruction.
    [Switching to Thread 0x7fffe2a60700 (LWP 14328)]
    0x00007fffecba4f3b in _xbegin () at ../nptl/sysdeps/unix/sysv/linux/x86/hle.h:53
    53  ../nptl/sysdeps/unix/sysv/linux/x86/hle.h: No such file or directory.
    

    Or:

    [0903/180140.360346:WARNING:discardable_shared_memory_manager.cc(411)] Some MojoDiscardableSharedMemoryManagerImpls are still alive. They will be leaked.
    [Thread 0x7fffe125d700 (LWP 14280) exited]
    [New Thread 0x7fffc9775700 (LWP 14318)]
    [0903/180140.363704:ERROR:process_posix.cc(330)] Unable to terminate process 14298: No such process (3)
    [0903/180140.363830:WARNING:internal_linux.cc(64)] Failed to read /proc/14298/stat
    [Thread 0x7fffaffff700 (LWP 14289) exited]
    [0903/180140.366239:WARNING:internal_linux.cc(64)] Failed to read /proc/14290/stat
    

    Or:

    ../nptl/pthread_mutex_lock.c:350: __pthread_mutex_lock_full: Assertion `(-(e)) != 3 || !robust' failed.
    Process finished with exit code 134 (interrupted by signal 6: SIGABRT)
    
  78. Alexsey

    @Marshall Greenblatt not work OnBeforeResourceLoad for service worker . I test in 78.0.3904.87

    You wrote that this will work after the implementation of NetworkService

  79. Marshall Greenblatt

    Convert usage and tests to the new CefResourceHandler API (see issue #2622)

    Limited test coverage for the old API is still available by passing the --test-old-resource-api command-line flag to ceftests.

    → <<cset 1c88c74f8682>>

  80. Marshall Greenblatt

    Convert usage and tests to the new CefResourceHandler API (see issue #2622)

    Limited test coverage for the old API is still available by passing the --test-old-resource-api command-line flag to ceftests.

    → <<cset e8680c0482a1>>

  81. Log in to comment