New issue
Advanced search Search tips

Issue 803149 link

Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Closed: Apr 2018
Cc:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug

Blocked on:
issue 746977
issue 753658

Blocking:
issue 598073



Sign in to add a comment

Get services/network working on iOS

Project Member Reported by jam@chromium.org, Jan 17 2018

Issue description

There are layered components that use net::URLFetcher. To convert them to use SimpleURLLoader so that they can work with the network service requires that iOS can also use SimpleURLLoader. This requires getting services/network up and running on iOS. NetworkContext would wrap the net::URLRequestContext that iOS owns.

services/network should be mostly moved within the next day or so hopefully.
 
Owner: sdefresne@chromium.org
Status: Started (was: Available)
Giving to sdefresne@ per offline discussion.
Project Member

Comment 2 by bugdroid1@chromium.org, Jan 25 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/c36931f5c3fb4ef5c2a379037bc69e11b5fc243e

commit c36931f5c3fb4ef5c2a379037bc69e11b5fc243e
Author: Sylvain Defresne <sdefresne@chromium.org>
Date: Thu Jan 25 17:08:27 2018

Fix dependencies of //services:services_unittests.

The dependency //services/network:tests was added twice when
is_ios was false. As the tests build and pass on iOS, remove
the second reference.

Bug:  803149 
Change-Id: I5e53070aafbf7c873e004df1188efdc495d24587
Reviewed-on: https://chromium-review.googlesource.com/887081
Commit-Queue: Sylvain Defresne <sdefresne@chromium.org>
Commit-Queue: Colin Blundell <blundell@chromium.org>
Reviewed-by: Colin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#531927}
[modify] https://crrev.com/c36931f5c3fb4ef5c2a379037bc69e11b5fc243e/services/BUILD.gn

Comment 3 by jam@chromium.org, Feb 1 2018

BTW here's a belated strawman of how we can do this:
-to unblock shipping network service to canary (or full launch really), we need code shared with iOS to stop using net/
  -note that code in src/ios can still use net/ freely
-so far, I'm only aware of net::URLFetcher
  -perhaps there's shared code that uses cookiemanager, if so we can apply the same logic as for requests. I'll skip that for now and use requests as one example
-the code can be converted to use SimpleURLLoader, which needs a mojom::URLLoaderFactory
-non-iOS code already has URLLoaderFactory. so the task here is to have a mojom::URLLoaderFactory* that we can pass from iOS to src/components

-we can bring up all of services/network: however most of it isn't needed to just handle requests (i.e. see the mojo interfaces for NetworkService or NetworkContext)
-so we can just have a way to create a URLLoaderFactory* that returns network::URLLoader implementations
  -we can reuse network::NetworkServiceURLLoaderFactory. however that does depend on NetworkService and NetworkContext and doesn't really add any interesting logic.
  -so on iOS, we can create a new URLLoaderFactory implementation that creates network::URLLoader objects

Thoughts?
Can we do just what we do in chrome?  Create a NetworkContext around the URLRequest, and use that?  We're going to want to switch to using NetworkContext's configuration logic, anyways.  Manual URLRequestContext configuration is a complete mess, and using a NetworkContext makes it still messy, but much less so.

This also makes things simpler going forward if, say, we need to share code that does DNS lookups, clears the cache, sets cookies, logs to NetLog to disk (Which *is* something I know we currently share a component for, not sure about the others) etc on iOS and non-iOSX platforms.

Comment 5 by jam@chromium.org, Feb 2 2018

I looked at the net/ includes of all components/ that are in DEPS files in src/ios. Notes:
-almost all the includes are either utility files (i.e. request/response header classes) or URLFetcher
-there were a couple of users of net::NetworkChangeNotifier: so we probably will need mojom::NetworkChangeManager implemented on iOS which shouldn't be much work
-components/proxy_config: I believe since the components use the net::ProxyConfigService, we can pass in ProxyConfigServiceMojo on non-IOS which implements that interface

Comment 6 by jam@chromium.org, Feb 2 2018

(our comments crossed :) )

Regarding using NeworkContext on iOS: yes that's a possibility. While simplifying iOS configuration sounds like a good eventual task, doing this work doesn't get us closer to canary or full launch on non-iOS.
I'd really like to get rid of all the configuration in ios_io_thread.mm - while we may not be able to completely share configuration, a lot of that is redundant (And having completely different configuration logic on iOS seems like a bad idea - right not, it's based on Chrome code, so is roughly similar).  Same goes for the browser_state files.

While doing this won't get us any closer to launch, I don't think there's any extra developer time in using NetworkContext on iOS from the start, and if it's where we want to go, seems like we should just go there from the start.

It also means I won't have to figure out how to make your changes compatible with the sidechannel stuff we discussed earlier this week, where URLLoaderFactories would live until all URLLoaders are gone.  Currently, looks like I may have to just junk my current CL to do that.

Comment 8 by jam@chromium.org, Feb 2 2018

I'd worry that doing any now-unnecessary changes on iOS will distract us, i.e. there could be bugs in conversions or we may need to add new features to the services/network code. Given that it's already duplicated, afaik people don't really change the other one when they change chrome or ios.

Regarding the side channel, perhaps we can VC to chat through some designs? My understanding from the chat earlier this week was that each URLLoader can take a refcount to an object that holds on to the side channel. So if we had a C++ refcounted classes that holds on to the mojom::NetworkServiceClient* (instead of passing it in directly), that should still work or am I missing something?
Refcounting seems not great, since there are times where we actually do want to destroy the URLLoaderFactory (dead side channel, NetworkContext going away).  So I had a CL that move the URLLoader list to the NetworkContext, and just kept it alive as long as is was non-empty, or there's a life URLLoaderFactory pipe, except in the case of shutdown.  I'm reluctant to rewrite that to layer yet another layer of lifetime complexity on top of the URLRequestContextGetter stuff.

Comment 10 by jam@chromium.org, Feb 2 2018

I meant ref count an object that owns the mojo sidechannel, it could be a C++ class whose only member variable is NetworkServiceClientPtr (whatever the per-frame replacement will be called). That wouldn't interfere with URLLoaderFactory lifetime?
Hey, John, coming up to speed on this conversation, so a possibly naive question.  In c#7 Matt indicates that he doesn't think that using NetworkContext on iOS will be any extra work to get to non-iOS canary launch compared to your plan, but in c#8 you seem to be concerned that it will (when you refer to being distracted by now-unnecessary changes on iOS).  Can you say more about why you think using NetworkContext on iOS is more complex than coming up with a new URLLoaderFactory implementation?  Naively, my instinct is with Matt that it's about the same (my gut says "less") work to go that way in the short term, and a lot less work to go that way in the long term.

(I'm avoiding diving into the details of implementing side channel designs--that's interesting, but ATM strikes me as a distraction from the key point, which is whether using NetworkContext on iOS costs us in time-to-canary-launch units.)

Comment 12 by jam@chromium.org, Feb 7 2018

@Randy re comment 11:

At a high level, on non-iOS we only want to access net/ through the network service. We need to finish that work before we canary. Then when we fully launch and delete the old pathway, the NetworkContext constructor that takes in a configured URLRequestContext would be gone.

On iOS, to use the same code path as we have on non-iOS means that all net/ access would have to go through network service (since eventually that's the only code path we'll have on non-iOS). That is a lot of work. With finite resources on network service effort, and especially with not much expertise on ios, this adds work & risk for very little gain.

I've been distracted by a high priority bug, hence the delay, but now I'm free and happy to VC to chat through this if you want.
Switching all iOS use over does not block Canary on any platform, so I'm not seeing why that's relevant here.  I'm also not seeing why an exposed URLLoaderFactory constructor is any better than an exposed NetworkContext one, particularly when using APIs as bad as URLRequestContextGetter has proven to be.

Comment 14 by jam@chromium.org, Feb 7 2018

@Matt

Regarding iOS, yes it doesn't block canary. What I was trying to show is that the only purpose of using NetworkContext, long term, would be when everything goes through NetworkContext. Do you not agree that the NetworkContext constructor which takes in a URLRequestContext will eventually be deleted?

Regarding URLRequestContextGetter, we can always change ownership to be by something other than that. I just used that for now because that's what iOS has, and it was lower level than other classes in network service. That bit of dependency is very small so can be easily changed.
John: I totally get that you don't want to do extra work on iOS beyond what's needed to get the non-iOS canary pushed.  The thing I *don't* get is why you think using a NetworkContext wrapper for that purpose would be more work than spinning up a special URLLoaderFactory.  My gut is that it wouldn't be very much work (now that everything's in //services/network, I *think* writing a utility class to do URLRequestContext -> NetworkContext would be a breeze) and my sense is that'd result in much less extra code and messy architecture at the URLLoaderFactory level.

A VCs almost certainly the right next step, but I wanted to probe at where you thought the complexity in the NetworkContext wrapper solution would be, in case we can make the problem vanish into mist before the rathole dive :-}.

I'd like to see that constructor deleted, yes, but less so than I'd like to see network::URLLoaderFactory used outside of services/network (Which is bing used to accomplish pretty much the exact same thing as that NetworkContext constructor).

Comment 17 by jam@chromium.org, Feb 7 2018

@Randy: NetworkServiceURLLoaderFactory depends on NetworkService and other classes that aren't needed on iOS. A new URLLoaderFactory implementation would be a trivial implementation (i.e. just construct network::URLLoader).

@Matt: can you give more background about why we need network::URLLoaderFactory used on iOS? I think that's the part that I'm missing.

And happy to do this over VC as well, I'm free all afternoon.
As we discussed over VC, I want to link the lifetime of the URLLoaderFactory to the lifetime of the URLLoaders (Keep the URLLoaderFactory alive as long as there's a sidechannel, if we were passed one on created, and either live URLLoaders or live URLLoaderFactories).  Yes, we could expose a delegate interface as well, or have the consumer on iOS keep a pipe alive, but things start getting hacky.

I also think that having circular lifetime dependences (URLLoaders keep the getter alive, and are destroyed by a message from the getter) are a problem, as are non-self-contained refcounted objects (If the getter outlives objects it points to, like the HostResolver and the NetworkContext's PrefService, we're in trouble), and if anything with a live pointer to the getter isn't destroyed on shutdown (Maybe there's a task that doesn't block shutdown that owns a pointer to it), then we lose state.

Comment 19 by jam@chromium.org, Feb 7 2018

@Matt: can you expand on what functionality you're trying to achieve (as opposed to the specific implementation)? I believe this is to have the URLLoader always able to call the side channel pipe right? If my understanding is correct, then there are several ways of implementing this without depending on URLLoaderFactory/NetworkContext. Before getting into those, I want to make sure this is what you're trying to solve.

Regarding circular lifetime dependencies, just to be clear I don't think I suggested that so I'm not sure which proposal you're referring to?
I want the side channel to stay alive as long as there's a URLLoaderFactory that's alive or a URLLoader that's using it.  I want to destroy all URLLoaders and URLLoaderFactories using a sidechannel if the side channel is destroyed.  I also want to remove reference counting of the ResourceScheduler (I don't think it's landed yet, but it's similarly scoped to a URLLoaderFactory and its clones).

The use of URLRequestContextGetter you added has the aforementioned circular lifetime dependency - that second paragraph was about the state of URLLoaders as they are now, using URLRequestContextGetter, not as they will be once they're used on iOS.

Comment 21 by jam@chromium.org, Feb 7 2018

Thanks, I have a few questions about this lifetime:
-what owns/destroys the side channel? If it's RenderFrameHost, how do we keep URLLoaders created for ping and other requests that outlive the frame alive?
-what happens when a URLLoaderFactory is cloned, does it inherit or create a new side channel object? I'm particularly curious about workers.


Regarding the second paragraph and your last explanation: I'm not sure I follow how the URLLoaders currently keep the getter alive?
-what owns/destroys the side channel? If it's RenderFrameHost, how do we keep URLLoaders created for ping and other requests that outlive the frame alive?

We discussed this when we met two weeks back, and decided to make it strongly bound to the side channel pipe.  It will, at least initially, have the render process and render frame IDs, just like the getters used by RDH, so can fetch the frame/WebContents at will, but still outlive their destruction.  So this should basically match behavior of the existing RDH->UI thread post tasks in the current world.

-what happens when a URLLoaderFactory is cloned, does it inherit or create a new side channel object? I'm particularly curious about workers.

I think just using a BindingSet and just reusing the same URLLoaderFactory is the simplest solution here.
Oh, and the URLLoaders hold onto a reference to the getter - they're storing one in a scoped_refptr.  https://cs.chromium.org/chromium/src/services/network/url_loader.h?type=cs&q=URLLoader&sq=package:chromium&l=107

Comment 24 by jam@chromium.org, Feb 7 2018

If the side channel on the browser side is strongly owned by the pipe, then the network service side is the one that has to initiate destruction. So how does a side channel object decide to destroy URLLoaderFactory/URLLoader using it?

"reusing the same URLLoaderFactory" I think you meant reusing the same side channel? (since when the URLLoaderFactory is cloned a new NetworkServiceURLLoaderFactory is created). If so, given that the side channel has in it information about the render frame ID, I think we would need to create a new side channel for shared workers at least, and maybe service workers as well.

Since URLLoaders can outlive their factory (e.g. ping), and the side channel is owned in the network process, did you consider refcounting an object that owns just the side channel (and not the factory). This object can be created when the URLLoaderFactory is created, and each child URLLoader can grab a reference (it would replace the mojom::NetworkServiceClient* they get now).

Regarding the URLLoader keeping the URLRequestContextGetter alive: when URLLoader::OnContextShuttingDown it will delete itself and so that would remove the reference, so I don't see a circular dependency?
When there are no URLLoaderFactory pipes / URLLoaders, the URLLoaderFactory destroys itself.

I mean the same URLLoaderFactory - we have one factory (With multiple pipes, cloned), one side channel.  I don't think we can trust renderer processes to provide new side channels, since we don't trust them for things like cert error bypasses, so Clone() necessarily means we use the same side channel.  Don't see any way around that.

I considered that, and dismissed it - refcounting is in general not a great ownership model, and I'd rather not have a refcounted "bag of stuff scoped to a URLLoaderFactory and its decendents that we hope doesn't leak".  My solution does use implicit refcounting of the URLLoaderFactory, but avoiding using base::Refcounted gives us much more control over invariants and lifetimes.

Also, URLLoader/Getter It's still a circular dependency, even if it's safe use of a circular dependency.  Problematic lifetime patterns can be used safely, but it increases the risk of breakage.  Also, if the getter is destroyed in the middle of a OnContextShuttingDown call to a URLLoader, it will crash (It isn't safe to destroy the getter in OnContextShuttingDown).  Sure, the owner is owning a reference, but if URLLoader has a hard dependency on that...Why does it even own a reference?

Comment 26 by jam@chromium.org, Feb 7 2018

We don't trust the renderer to say which render_process_id a request is from, but we will have to trust it when it says which frame or worker it's from (since an exploited renderer can just use a different mojo pipe). I think clone() will have to create a new factory and side channel for a few reasons:
-window.open with a blank url currently uses clone to get its own URLLoaderFactory objects. These have different render_frame_id
-workers can't share the same side channel, because for example shared workers aren't associated with a specific frame
-we are planning on adding security information to each URLLoaderFactory, i.e. which origins it has access to. this means that they can't be shared with any other context, as we have to ensure that one URLLoaderFactory can be mapped to a single RenderFrame (or other types of objects)

This seems to come down to a tradeoff of having URLLoader know about NetworkContext and/or URLLoaderFactory implementation vs having a URLLoader be reused outside of network service without other dependencies. TBH I'm having a bit of a difficulty seeing why you're opposed to a refcounted class that holds on to the side channel pipe (doesn't have to contain anything else). At this point I think a VC is the most efficient way to discuss this.

Re URLLoader/Getter, we can switch URLLoader to own a naked pointer to URLLoaderGetter. Both ways seem fine to me but if you care about strongly then I'm fine with switching it (assuming it still ends up looking that way).

FWIW here's a cl using URLLoader on iOS: https://chromium-review.googlesource.com/c/chromium/src/+/907543. I haven't figured out how to write a test for this, but adding it in case it clarifies anything.
I'm not concerned about it lying about what frame it's from, but from it abusing the power the side channel will give it.  The entire reason for the side channel in the first place is that we can't trust the renderer to do the things the side channel needs to be able to do.  Otherwise, we could just beef up the URLLoader interface with the needed calls.

If we need a new side channel, we'll have to request the new URLLoader from the browser process.
I feel strongly about getting rid of URLRequestContextGetter, which means not using it at all in the NetworkService.  It costs us basically nothing to do that.
And as for what the side channel would do - basically what ContextNetworkClient does, just without needing the network service to provide the network service to provide the routing ID and process ID.  Haven't thought about ResourceType.

Comment 30 by jam@chromium.org, Feb 7 2018

Yep I think we're all on the same page regarding the purpose of the side channel. The security calls are already not going from the renderer. We could start a discussion about changing how workers or window.open get their URLLoaderFactory. Although if creating a per-factory side channel instead of the global approach today involves modifying these code paths and is > 1 week of work, then we should figure out what we're gaining and think about punting it as it doesn't get us closer to canary and doesn't change the security story. We will need to keep sending render_frame_id in ResourceRequest until network service is launched on all platforms, as the old code path requires it.

Regarding URLRequestContextGetter, as I mentioned above I'm totally not wedded to that. I used it because it existed. If we're getting rid of it in the codebase (I see 1500 files using it in cs/), then it would be trivial to change it. As a strawman, we can add an intermediate class that can be shared with iOS that handles the lifetime management.
Those 1,500 files are mostly in code that will need to be in the browser process, so we'll necessary need to get rid of it basically everywhere, anyways (Modulo iOS and Cronet).  That's also why this is a good time to get rid of it (At least mostly).
Project Member

Comment 32 by bugdroid1@chromium.org, Feb 8 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/07a93f108f0d32218e13e843789fbaa525c3bb82

commit 07a93f108f0d32218e13e843789fbaa525c3bb82
Author: John Abd-El-Malek <jam@chromium.org>
Date: Thu Feb 08 19:28:25 2018

Add a URLLoaderFactory implementation in src/ios for use by components.

This is backed by services/network/url_loader implementation. This allows components that are
shared with src/chrome to use URLLoader instead of URLFetcher.

Old:
Layered components take BrowserState::GetRequestContext() and pass it to to net::URLFetcher.

New:
Layered components take BrowserState::GetURLLoaderFactory() and pass it to network::SimpleURLLoader.

Bug:  803149 
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: Ie4723ca17467f0372eed4d999544351152702e3e
Reviewed-on: https://chromium-review.googlesource.com/907543
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Reviewed-by: Eugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#535472}
[modify] https://crrev.com/07a93f108f0d32218e13e843789fbaa525c3bb82/ios/DEPS
[modify] https://crrev.com/07a93f108f0d32218e13e843789fbaa525c3bb82/ios/web/BUILD.gn
[modify] https://crrev.com/07a93f108f0d32218e13e843789fbaa525c3bb82/ios/web/DEPS
[modify] https://crrev.com/07a93f108f0d32218e13e843789fbaa525c3bb82/ios/web/browser_state.mm
[modify] https://crrev.com/07a93f108f0d32218e13e843789fbaa525c3bb82/ios/web/public/browser_state.h
[modify] https://crrev.com/07a93f108f0d32218e13e843789fbaa525c3bb82/ios/web/public/test/web_test.h
[modify] https://crrev.com/07a93f108f0d32218e13e843789fbaa525c3bb82/ios/web/public/test/web_test.mm
[add] https://crrev.com/07a93f108f0d32218e13e843789fbaa525c3bb82/ios/web/url_loader_inttest.mm

Here's my suggestion:  Make URLLoader's constructor take a network::URLLoaderFactory instead of a URLLoader.  URLLoaderFactory's constructor takes an (optional) callback, which it invokes when it has no pipes and no live loaders.  URLLoaderFactories keep track of their live URLLoaders, and destroy them on its destruction, but have no logic to destroy themselves directly.

After we add a sidechannel, we can invoke the callback as well.

That gets us no use of NetworkContext or NetworkService on iOS (Which I think you want?), and lets us just use URLLoaderFactory directly on iOS.  We just make sure to destroy it before the URLRequestContext, and we're good.

How does that sound?

Comment 34 by jam@chromium.org, Feb 10 2018

To make sure I'm understanding:
-since NetworkContext isn't passed in, how will URLLoaderFactory::Clone get implemented? 
-I assume we'll also need to pass in a few more things, like the statisticsrecorder, networkserviceclient
-how will the raw header check be implemented, through another callback?
-network::URLLoaderFactory assumes that it's on the same thread as URLLoader. On iOS, URLLoaderFactory* is called on a different thread (the main one)

Because of these differences, it's not clear to me that there's much to gain by sharing network::URLLoaderFactory. i.e. can we do the lifetime management in a helper class instead and store that as a member in network::URLLoaderFactory? Only question is, how do we do this on iOS because URLLoaderFactory implementation there lives on UI thread?
URLLoaderFactory::Clone will work by just adding another binding to a binding set.  We'll need to worry about how to handle side channels with new RFH IDs, but Cone() doesn't take those currently, anyways, they're passed in when creating a URLRequest.  In the future, we won't want to be passing Clone() a render frame ID anyways.

We pass in to the URLLoaderFactory the StatisticsRecorder and anything else we'll need.  I hadn't noticed the headers check - I'm fine with just passing in the NetworkContext, and allowing it to be a null one.

Fundamentally, here are my concerns:
1)  URLRequestContextGetter is unsafe.  We should not use it.
2)  More generally, I don't want us to pepper the network service with refcounted objects.  Shared refcounted objects are a design anti-pattern, have led to large numbers of problems before, and will continue to do so.

I want to come up with something we can both live with.  The network stack team is going to be maintaining this code, and I don't want to leave us with large amounts of technical debt to pay down, if we can spend orders of magnitude less effort now and avoid it being an issue in the future.

I'm not seeing why calling URLLoaderFactory on another thread is a problem on iOS?  We call it on another thread and another process on desktop.  We just use a Mojo pipe, and we're fine, no?
Left to my own devices, I'd just hook up a NetworkService and a NetworkContext on iOS, with the sharing pattern on desktop, which wouldn't take much effort and would require no special iOS/not-iOS code paths in the short term, though we'd have to keep the passed-in URLRequestContext pattern around for a while.
John and I talked about this offline.

The conclusion was I'd go ahead and instantiate NetworkService and NetworkContexts on iOS, and have them wrap URLRequestContexts created on iOS, just like we do in other (non-Chrome) content/ embedders. This should only take me a couple days.  We'll need to keep this path around for a while, anyways, and this will result in exercising the same code path on more platforms. While we could just make URLLoaders use a delegate interface with a bunch of methods that return null on non-iOS platforms, that would potentially result in maintaining more code paths that we won't be keeping longer term.

We should not extend any effort to convert iOS-only network code to use the network service until after the network service has shipped, to avoid delaying when we can ship the network service.
Hey Matt,

will Sylvain's in-progress CL for bringing up the Network Service on iOS be useful here?

https://chromium-review.googlesource.com/c/chromium/src/+/887064

This CL was created before the Network Service proper was moved into //services/network; the goal was to update it once those code moves finished.

Comment 39 by jam@chromium.org, Feb 13 2018

@Colin: that cl will only be needed if code connects to the NetworkService interface. I don't think we'll have that need, as the ios code will have to initialize the C++ classes directly as it'll still own the net::URLRequestContext.
OK! Sylvain and I discussed and we'll definitely let Matt handle the bringup from here :). Matt: Give us a shout if there are any iOS-specific issues you would like any help with!
Thanks, will do.  I probably won't get to this for a week or so, just FYI.
Owner: mmenke@chromium.org
Status: Assigned (was: Started)
It looks like CL added in comment #32 (https://chromium-review.googlesource.com/907543) does introduce some DCHECK when running ios_chrome_unittests. I can reproduce it reliably on my machine if I run the all the tests, but I only run a subset, then there is no DCHECK.

The failure looks like:

[ RUN      ] IOSSSLErrorHandlerTest.NonOverridable
[40644:771:0220/170954.228862:13025776643406:FATAL:message_loop.h(504)] Check failed: MessageLoop::TYPE_IO == loop->type() (3 vs. 1)

The callstack at the time of the DCHECK is:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0)
  * frame #0: 0x00000001026460e4 ios_chrome_unittests`base::debug::BreakDebugger() at debugger_posix.cc:269
    frame #1: 0x00000001026a741c ios_chrome_unittests`logging::LogMessage::~LogMessage(this=0x00007ffeef9f6338) at logging.cc:842
    frame #2: 0x00000001026a3ea5 ios_chrome_unittests`logging::LogMessage::~LogMessage(this=0x00007ffeef9f6338) at logging.cc:575
    frame #3: 0x0000000103a502dc ios_chrome_unittests`base::MessageLoopForIO::current() at message_loop.h:504
    frame #4: 0x0000000103a4f891 ios_chrome_unittests`net::URLRequestFilter::MaybeInterceptRequest(this=0x000062c000093920, request=0x00007f9ffc06f000, network_delegate=0x0000000000000000) const at url_request_filter.cc:116
    frame #5: 0x0000000103a7c333 ios_chrome_unittests`net::URLRequestJobFactoryImpl::MaybeCreateJobWithProtocolHandler(this=0x00006000000f3700, scheme="http", request=0x00007f9ffc06f000, network_delegate=0x0000000000000000) const at url_request_job_factory_impl.cc:51
    frame #6: 0x0000000103a7f5cb ios_chrome_unittests`net::URLRequestJobManager::CreateJob(this=0x000062c000207750, request=0x00007f9ffc06f000, network_delegate=0x0000000000000000) const at url_request_job_manager.cc:72
    frame #7: 0x0000000103a20c44 ios_chrome_unittests`net::URLRequest::Start(this=0x00007f9ffc06f000) at url_request.cc:542
    frame #8: 0x000000010521c4c4 ios_chrome_unittests`network::URLLoader::URLLoader(this=0x00007f9ff9f12fa0, url_request_context_getter=scoped_refptr<net::URLRequestContextGetter> @ 0x00007ffeef9f84d8, network_service_client=0x0000000000000000, url_loader_request=network::mojom::URLLoaderRequest @ 0x00007ffeef9f84d0, options=0, request=0x00007f9fff20d860, report_raw_headers=false, url_loader_client=network::mojom::URLLoaderClientPtr @ 0x00007ffeef9f8518, traffic_annotation=0x00007ffeef9f84c8, process_id=0, resource_scheduler_client=scoped_refptr<network::ResourceSchedulerClient> @ 0x00007ffeef9f84c0, keepalive_statistics_recorder=WeakPtr<network::KeepaliveStatisticsRecorder> @ 0x00007ffeef9f84b0) at url_loader.cc:332
    frame #9: 0x000000010521fcff ios_chrome_unittests`network::URLLoader::URLLoader(this=0x00007f9ff9f12fa0, url_request_context_getter=<unavailable>, network_service_client=0x0000000000000000, url_loader_request=<unavailable>, options=0, request=0x00007f9fff20d860, report_raw_headers=false, url_loader_client=network::mojom::URLLoaderClientPtr @ 0x00007ffeef9f8518, traffic_annotation=0x00007ffeef9f84c8, process_id=0, resource_scheduler_client=<unavailable>, keepalive_statistics_recorder=<unavailable>) at url_loader.cc:269
    frame #10: 0x00000001012be51c ios_chrome_unittests`web::BrowserState::URLLoaderFactory::CreateLoaderAndStartOnIO(request_getter=scoped_refptr<net::URLRequestContextGetter> @ 0x00007ffeef9f85f8, request=network::mojom::URLLoaderRequest @ 0x00007ffeef9f85f0, routing_id=0, request_id=0, options=0, resource_request=0x00007f9fff20d860, client_info=network::mojom::URLLoaderClientPtrInfo @ 0x00007ffeef9f85d8, traffic_annotation=0x00007f9fff20db60) at browser_state.mm:146
    frame #11: 0x00000001012bf084 ios_chrome_unittests`void base::internal::FunctorTraits<void (*)(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&), void>::Invoke<scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag>(function=(ios_chrome_unittests`web::BrowserState::URLLoaderFactory::CreateLoaderAndStartOnIO(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&) at browser_state.mm:143), args=0x00007f9fff20d848, args=0x00007f9fff20d850, args=0x00007f9fff20d854, args=0x00007f9fff20d858, args=0x00007f9fff20d85c, args=0x00007f9fff20d860, args=0x00007f9fff20db58, args=0x00007f9fff20db60)(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&), scoped_refptr<net::URLRequestContextGetter>&&, mojo::InterfaceRequest<network::mojom::URLLoader>&&, int&&, int&&, unsigned int&&, network::ResourceRequest&&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>&&, net::MutableNetworkTrafficAnnotationTag&&) at bind_internal.h:402
    frame #12: 0x00000001012bede7 ios_chrome_unittests`void base::internal::InvokeHelper<false, void>::MakeItSo<void (functor=0x00007f9fff20d840, args=0x00007f9fff20d848, args=0x00007f9fff20d850, args=0x00007f9fff20d854, args=0x00007f9fff20d858, args=0x00007f9fff20d85c, args=0x00007f9fff20d860, args=0x00007f9fff20db58, args=0x00007f9fff20db60)(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&), scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag>(void (*&&)(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&), scoped_refptr<net::URLRequestContextGetter>&&, mojo::InterfaceRequest<network::mojom::URLLoader>&&, int&&, int&&, unsigned int&&, network::ResourceRequest&&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>&&, net::MutableNetworkTrafficAnnotationTag&&) at bind_internal.h:530
    frame #13: 0x00000001012bed06 ios_chrome_unittests`void base::internal::Invoker<base::internal::BindState<void (*)(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&), scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag>, void ()>::RunImpl<void (functor=0x00007f9fff20d840, bound=0x00007f9fff20d848, (null)=std::__1::index_sequence<0UL, 1UL, 2UL, 3UL, 4UL, 5UL, 6UL, 7UL> @ 0x00007ffeef9f87c0)(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&), std::__1::tuple<scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag>, 0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul>(void (*&&)(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&), std::__1::tuple<scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag>&&, std::__1::integer_sequence<unsigned long, 0ul, 1ul, 2ul, 3ul, 4ul, 5ul, 6ul, 7ul>) at bind_internal.h:604
    frame #14: 0x00000001012be979 ios_chrome_unittests`base::internal::Invoker<base::internal::BindState<void (*)(scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest const&, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag const&), scoped_refptr<net::URLRequestContextGetter>, mojo::InterfaceRequest<network::mojom::URLLoader>, int, int, unsigned int, network::ResourceRequest, mojo::InterfacePtrInfo<network::mojom::URLLoaderClient>, net::MutableNetworkTrafficAnnotationTag>, void ()>::RunOnce(base=0x00007f9fff20d820) at bind_internal.h:572
    frame #15: 0x00000001011a7ad1 ios_chrome_unittests`base::OnceCallback<void ()>::Run(this=0x00007ffeef9f9068) && at callback.h:95
    frame #16: 0x0000000102649688 ios_chrome_unittests`base::debug::TaskAnnotator::RunTask(this=0x00007f9fff202e70, queue_function="MessageLoop::PostTask", pending_task=0x00007ffeef9f9068) at task_annotator.cc:55
    frame #17: 0x00000001026c707a ios_chrome_unittests`base::internal::IncomingTaskQueue::RunTask(this=0x00007f9fff202e10, pending_task=0x00007ffeef9f9068) at incoming_task_queue.cc:124
    frame #18: 0x00000001026d38dc ios_chrome_unittests`base::MessageLoop::RunTask(this=0x00007f9fff202c80, pending_task=0x00007ffeef9f9068) at message_loop.cc:395
    frame #19: 0x00000001026d3ea9 ios_chrome_unittests`base::MessageLoop::DeferOrRunPendingTask(this=0x00007f9fff202c80, pending_task=PendingTask @ 0x00007ffeef9f9068) at message_loop.cc:407
    frame #20: 0x00000001026d41d9 ios_chrome_unittests`base::MessageLoop::DoWork(this=0x00007f9fff202c80) at message_loop.cc:451
    frame #21: 0x00000001026dcdf1 ios_chrome_unittests`base::MessagePumpDefault::Run(this=0x00006240000565f0, delegate=0x00007f9fff202c80) at message_pump_default.cc:37
    frame #22: 0x00000001026d308d ios_chrome_unittests`base::MessageLoop::Run(this=0x00007f9fff202c80, application_tasks_allowed=true) at message_loop.cc:346
    frame #23: 0x000000010279346e ios_chrome_unittests`base::RunLoop::Run(this=0x00007ffeef9f9ef0) at run_loop.cc:133
    frame #24: 0x00000001027942e2 ios_chrome_unittests`base::RunLoop::RunUntilIdle(this=0x00007ffeef9f9ef0) at run_loop.cc:146
    frame #25: 0x0000000101e9fe65 ios_chrome_unittests`web::TestWebThreadBundle::~TestWebThreadBundle(this=0x00007f9fff201668) at test_web_thread_bundle.cc:30
    frame #26: 0x0000000101ea0545 ios_chrome_unittests`web::TestWebThreadBundle::~TestWebThreadBundle(this=0x00007f9fff201668) at test_web_thread_bundle.cc:26
    frame #27: 0x0000000101e4abf5 ios_chrome_unittests`web::WebTest::~WebTest(this=0x00007f9fff201640) at web_test.mm:36
    frame #28: 0x0000000101e4b9e1 ios_chrome_unittests`web::WebTestWithWebState::~WebTestWithWebState(this=0x00007f9fff201640) at web_test_with_web_state.mm:43
    frame #29: 0x000000010056a5e3 ios_chrome_unittests`IOSSSLErrorHandlerTest::~IOSSSLErrorHandlerTest(this=0x00007f9fff201640) at ios_ssl_error_handler_unittest.mm:30
    frame #30: 0x000000010056a4c5 ios_chrome_unittests`IOSSSLErrorHandlerTest_NonOverridable_Test::~IOSSSLErrorHandlerTest_NonOverridable_Test(this=0x00007f9fff201640) at ios_ssl_error_handler_unittest.mm:63
    frame #31: 0x00000001005693e5 ios_chrome_unittests`IOSSSLErrorHandlerTest_NonOverridable_Test::~IOSSSLErrorHandlerTest_NonOverridable_Test(this=0x00007f9fff201640) at ios_ssl_error_handler_unittest.mm:63
    frame #32: 0x0000000100569409 ios_chrome_unittests`IOSSSLErrorHandlerTest_NonOverridable_Test::~IOSSSLErrorHandlerTest_NonOverridable_Test(this=0x00007f9fff201640) at ios_ssl_error_handler_unittest.mm:63
    frame #33: 0x0000000100c0e91b ios_chrome_unittests`testing::Test::DeleteSelf_(this=0x00007f9fff201640) at gtest.h:453
    frame #34: 0x0000000100c31f7e ios_chrome_unittests`void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(object=0x00007f9fff201640, method=f0 e8 c0 00 01 00 00 00 00 00 00 00 00 00 00 00, location="the test fixture's destructor")(), char const*) at gtest.cc:2401
    frame #35: 0x0000000100c0d882 ios_chrome_unittests`void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(object=0x00007f9fff201640, method=f0 e8 c0 00 01 00 00 00 00 00 00 00 00 00 00 00, location="the test fixture's destructor")(), char const*) at gtest.cc:2454
    frame #36: 0x0000000100c0e775 ios_chrome_unittests`testing::TestInfo::Run(this=0x00007f9ffca2e850) at gtest.cc:2656
    frame #37: 0x0000000100c0fa3c ios_chrome_unittests`testing::TestCase::Run(this=0x00007f9ffca2e960) at gtest.cc:2769
    frame #38: 0x0000000100c1cffb ios_chrome_unittests`testing::internal::UnitTestImpl::RunAllTests(this=0x00007f9ffca00340) at gtest.cc:4665
    frame #39: 0x0000000100c34d2e ios_chrome_unittests`bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(object=0x00007f9ffca00340, method=60 cc c1 00 01 00 00 00 00 00 00 00 00 00 00 00, location="auxiliary test code (environments or event listeners)")(), char const*) at gtest.cc:2401
    frame #40: 0x0000000100c1cbe2 ios_chrome_unittests`bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(object=0x00007f9ffca00340, method=60 cc c1 00 01 00 00 00 00 00 00 00 00 00 00 00, location="auxiliary test code (environments or event listeners)")(), char const*) at gtest.cc:2454
    frame #41: 0x0000000100c1cad9 ios_chrome_unittests`testing::UnitTest::Run(this=0x0000000106fc7378) at gtest.cc:4277
    frame #42: 0x00000001029b8bb1 ios_chrome_unittests`RUN_ALL_TESTS() at gtest.h:2233
    frame #43: 0x00000001029b7fee ios_chrome_unittests`base::TestSuite::Run(this=0x00007ffeef9fd120) at test_suite.cc:272
    frame #44: 0x00000001029be501 ios_chrome_unittests`::-[ChromeUnitTestDelegate runTests](self=0x000061000001ddd0, _cmd="runTests") at test_support_ios.mm:157
    frame #45: 0x0000000110d9ff35 Foundation`__NSFireDelayedPerform + 409
    frame #46: 0x000000010fad6174 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
    frame #47: 0x000000010fad5e32 CoreFoundation`__CFRunLoopDoTimer + 1026
    frame #48: 0x000000010fad59ea CoreFoundation`__CFRunLoopDoTimers + 266
    frame #49: 0x000000010facd404 CoreFoundation`__CFRunLoopRun + 2308
    frame #50: 0x000000010facc889 CoreFoundation`CFRunLoopRunSpecific + 409
    frame #51: 0x0000000115b099c6 GraphicsServices`GSEventRunModal + 62
    frame #52: 0x000000010d8ac5d6 UIKit`UIApplicationMain + 159
    frame #53: 0x00000001029be842 ios_chrome_unittests`base::RunTestsFromIOSApp() at test_support_ios.mm:213
    frame #54: 0x00000001029b7ebf ios_chrome_unittests`base::TestSuite::Run(this=0x00007ffeef9fd120) at test_suite.cc:253
    frame #55: 0x000000010020417d ios_chrome_unittests`int base::internal::FunctorTraits<int (base::TestSuite::*)(), void>::Invoke<IOSChromeUnitTestSuite*>(method=a0 7e 9b 02 01 00 00 00 00 00 00 00 00 00 00 00, receiver_ptr=0x00007ffeef9fca50)(), IOSChromeUnitTestSuite*&&) at bind_internal.h:447
    frame #56: 0x00000001002040c4 ios_chrome_unittests`int base::internal::InvokeHelper<false, int>::MakeItSo<int (functor=0x000062c000265820, args=0x00007ffeef9fca50)(), IOSChromeUnitTestSuite*>(int (base::TestSuite::* const&&&)(), IOSChromeUnitTestSuite*&&) at bind_internal.h:530
    frame #57: 0x0000000100204075 ios_chrome_unittests`int base::internal::Invoker<base::internal::BindState<int (base::TestSuite::*)(), base::internal::UnretainedWrapper<IOSChromeUnitTestSuite> >, int ()>::RunImpl<int (functor=0x000062c000265820, bound=0x000062c000265830, (null)=std::__1::index_sequence<0UL> @ 0x00007ffeef9fca68)(), std::__1::tuple<base::internal::UnretainedWrapper<IOSChromeUnitTestSuite> > const&, 0ul>(int (base::TestSuite::* const&&&)(), std::__1::tuple<base::internal::UnretainedWrapper<IOSChromeUnitTestSuite> > const&&&, std::__1::integer_sequence<unsigned long, 0ul>) at bind_internal.h:604
    frame #58: 0x0000000100203f8c ios_chrome_unittests`base::internal::Invoker<base::internal::BindState<int (base::TestSuite::*)(), base::internal::UnretainedWrapper<IOSChromeUnitTestSuite> >, int ()>::Run(base=0x000062c000265800) at bind_internal.h:586
    frame #59: 0x00000001029c098d ios_chrome_unittests`base::RepeatingCallback<int ()>::Run(this=0x00007ffeef9fcf10) const & at callback.h:124
    frame #60: 0x00000001029c090d ios_chrome_unittests`base::LaunchUnitTests(argc=1, argv=0x00007ffeef9fd1c0, run_test_suite=0x00007ffeef9fcf10)> const&) at unit_test_launcher_ios.cc:39
    frame #61: 0x0000000100202a82 ios_chrome_unittests`main(argc=1, argv=0x00007ffeef9fd1c0) at run_all_unittests.cc:24
    frame #62: 0x0000000116ed2d81 libdyld.dylib`start + 1

The code task executed was posted from BrowserState::URLLoaderFactory::CreateLoaderAndStart called indirectly from CaptivePortalDetector::DetectCaptivePortal.

Callstack when the task is posted:
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x000000010e636fc5 ios_chrome_unittests`web::BrowserState::URLLoaderFactory::CreateLoaderAndStart(this=0x000061400000e9d0, request=network::mojom::URLLoaderRequest @ 0x00007ffee267edc8, routing_id=0, request_id=0, options=0, resource_request=0x00007fd7f5b046e0, client=network::mojom::URLLoaderClientPtr @ 0x00007ffee267ef18, traffic_annotation=0x00007ffee267edb8) at browser_state.mm:122
    frame #1: 0x00000001125ec2b6 ios_chrome_unittests`network::(anonymous namespace)::SimpleURLLoaderImpl::StartRequest(this=0x00007fd7f5b09ef0, url_loader_factory=0x000061400000e9d0) at simple_url_loader.cc:1267
    frame #2: 0x00000001125e7314 ios_chrome_unittests`network::(anonymous namespace)::SimpleURLLoaderImpl::Start(this=0x00007fd7f5b09ef0, url_loader_factory=0x000061400000e9d0) at simple_url_loader.cc:1246
    frame #3: 0x00000001125e161e ios_chrome_unittests`network::(anonymous namespace)::SimpleURLLoaderImpl::DownloadToStringOfUnboundedSizeUntilCrashAndDie(this=0x00007fd7f5b09ef0, url_loader_factory=0x000061400000e9d0, body_as_string_callback=<unavailable>)>) at simple_url_loader.cc:1054
  * frame #4: 0x000000011324e9b9 ios_chrome_unittests`captive_portal::CaptivePortalDetector::DetectCaptivePortal(this=0x00006140000c8ab0, url=0x00007ffee26803e8, detection_callback=0x00007ffee26803d0, traffic_annotation=0x00007ffee26803c0)> const&, net::NetworkTrafficAnnotationTag const&) at captive_portal_detector.cc:54
    frame #5: 0x000000010ef6f70c ios_chrome_unittests`IOSSSLErrorHandler::RecordCaptivePortalState(web_state=0x00007fd7f5b082d0) at ios_ssl_error_handler.mm:165
    frame #6: 0x000000010ef6f0e1 ios_chrome_unittests`IOSSSLErrorHandler::StartHandlingError(this=0x00007fd7f5b09cf0) at ios_ssl_error_handler.mm:77
    frame #7: 0x000000010ef6ec77 ios_chrome_unittests`IOSSSLErrorHandler::HandleSSLError(web_state=0x00007fd7f5b082d0, cert_error=-202, info=0x00007ffee26810e8, request_url=0x00007ffee2680ed0, overridable=false, callback=0x00007ffee2680e70)> const&) at ios_ssl_error_handler.mm:55
    frame #8: 0x000000010d8df9e2 ios_chrome_unittests`IOSSSLErrorHandlerTest_NonOverridable_Test::TestBody(this=0x00007fd7f5b01bb0) at ios_ssl_error_handler_unittest.mm:71
    frame #9: 0x000000010dfaaf7e ios_chrome_unittests`void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(object=0x00007fd7f5b01bb0, method=21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00, location="the test body")(), char const*) at gtest.cc:2401
    frame #10: 0x000000010df86882 ios_chrome_unittests`void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(object=0x00007fd7f5b01bb0, method=21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00, location="the test body")(), char const*) at gtest.cc:2454
    frame #11: 0x000000010df867b6 ios_chrome_unittests`testing::Test::Run(this=0x00007fd7f5b01bb0) at gtest.cc:2473
    frame #12: 0x000000010df8772d ios_chrome_unittests`testing::TestInfo::Run(this=0x00007fd7f592e850) at gtest.cc:2651
    frame #13: 0x000000010df88a3c ios_chrome_unittests`testing::TestCase::Run(this=0x00007fd7f592e960) at gtest.cc:2769
    frame #14: 0x000000010df95ffb ios_chrome_unittests`testing::internal::UnitTestImpl::RunAllTests(this=0x00007fd7f5900340) at gtest.cc:4665
    frame #15: 0x000000010dfadd2e ios_chrome_unittests`bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(object=0x00007fd7f5900340, method=60 5c f9 0d 01 00 00 00 00 00 00 00 00 00 00 00, location="auxiliary test code (environments or event listeners)")(), char const*) at gtest.cc:2401
    frame #16: 0x000000010df95be2 ios_chrome_unittests`bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(object=0x00007fd7f5900340, method=60 5c f9 0d 01 00 00 00 00 00 00 00 00 00 00 00, location="auxiliary test code (environments or event listeners)")(), char const*) at gtest.cc:2454
    frame #17: 0x000000010df95ad9 ios_chrome_unittests`testing::UnitTest::Run(this=0x0000000114340378) at gtest.cc:4277
    frame #18: 0x000000010fd31bb1 ios_chrome_unittests`RUN_ALL_TESTS() at gtest.h:2233
    frame #19: 0x000000010fd30fee ios_chrome_unittests`base::TestSuite::Run(this=0x00007ffee2684120) at test_suite.cc:272
    frame #20: 0x000000010fd37501 ios_chrome_unittests`::-[ChromeUnitTestDelegate runTests](self=0x000060400000de00, _cmd="runTests") at test_support_ios.mm:157
    frame #21: 0x000000011dcc7f35 Foundation`__NSFireDelayedPerform + 409
    frame #22: 0x000000011ce4f174 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
    frame #23: 0x000000011ce4ee32 CoreFoundation`__CFRunLoopDoTimer + 1026
    frame #24: 0x000000011ce4e9ea CoreFoundation`__CFRunLoopDoTimers + 266
    frame #25: 0x000000011ce46404 CoreFoundation`__CFRunLoopRun + 2308
    frame #26: 0x000000011ce45889 CoreFoundation`CFRunLoopRunSpecific + 409
    frame #27: 0x0000000122de09c6 GraphicsServices`GSEventRunModal + 62
    frame #28: 0x000000011ac255d6 UIKit`UIApplicationMain + 159
    frame #29: 0x000000010fd37842 ios_chrome_unittests`base::RunTestsFromIOSApp() at test_support_ios.mm:213
    frame #30: 0x000000010fd30ebf ios_chrome_unittests`base::TestSuite::Run(this=0x00007ffee2684120) at test_suite.cc:253
    frame #31: 0x000000010d57d17d ios_chrome_unittests`int base::internal::FunctorTraits<int (base::TestSuite::*)(), void>::Invoke<IOSChromeUnitTestSuite*>(method=a0 0e d3 0f 01 00 00 00 00 00 00 00 00 00 00 00, receiver_ptr=0x00007ffee2683a50)(), IOSChromeUnitTestSuite*&&) at bind_internal.h:447
    frame #32: 0x000000010d57d0c4 ios_chrome_unittests`int base::internal::InvokeHelper<false, int>::MakeItSo<int (functor=0x0000610000265f60, args=0x00007ffee2683a50)(), IOSChromeUnitTestSuite*>(int (base::TestSuite::* const&&&)(), IOSChromeUnitTestSuite*&&) at bind_internal.h:530
    frame #33: 0x000000010d57d075 ios_chrome_unittests`int base::internal::Invoker<base::internal::BindState<int (base::TestSuite::*)(), base::internal::UnretainedWrapper<IOSChromeUnitTestSuite> >, int ()>::RunImpl<int (functor=0x0000610000265f60, bound=0x0000610000265f70, (null)=std::__1::index_sequence<0UL> @ 0x00007ffee2683a68)(), std::__1::tuple<base::internal::UnretainedWrapper<IOSChromeUnitTestSuite> > const&, 0ul>(int (base::TestSuite::* const&&&)(), std::__1::tuple<base::internal::UnretainedWrapper<IOSChromeUnitTestSuite> > const&&&, std::__1::integer_sequence<unsigned long, 0ul>) at bind_internal.h:604
    frame #34: 0x000000010d57cf8c ios_chrome_unittests`base::internal::Invoker<base::internal::BindState<int (base::TestSuite::*)(), base::internal::UnretainedWrapper<IOSChromeUnitTestSuite> >, int ()>::Run(base=0x0000610000265f40) at bind_internal.h:586
    frame #35: 0x000000010fd3998d ios_chrome_unittests`base::RepeatingCallback<int ()>::Run(this=0x00007ffee2683f10) const & at callback.h:124
    frame #36: 0x000000010fd3990d ios_chrome_unittests`base::LaunchUnitTests(argc=1, argv=0x00007ffee26841c0, run_test_suite=0x00007ffee2683f10)> const&) at unit_test_launcher_ios.cc:39
    frame #37: 0x000000010d57ba82 ios_chrome_unittests`main(argc=1, argv=0x00007ffee26841c0) at run_all_unittests.cc:24
    frame #38: 0x00000001241add81 libdyld.dylib`start + 1

Comment 44 by jam@chromium.org, Feb 20 2018

Thanks for the report. Is this showing up on bots now? If so, can you please disable it in the meantime (I'm on a plane). I'll send a cl later with a fix for this.
Project Member

Comment 45 by bugdroid1@chromium.org, Feb 22 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/688c0d5295aabfafb7dc192cb1729fc3d8552527

commit 688c0d5295aabfafb7dc192cb1729fc3d8552527
Author: John Abd-El-Malek <jam@chromium.org>
Date: Thu Feb 22 20:06:55 2018

Fix check in ios_chrome_unittests after r535472.

The problem is that the IOSSSLErrorHandlerTest were indirectly creating network requests which depended on the message loop type being an IO thread. The tests don't actually need to make a network request, so fix it by using a TestURLLoaderFactory.

Bug:  803149 
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I4b8573bd3b5a378f3afe5de307045d4c6daa7b4f
Reviewed-on: https://chromium-review.googlesource.com/926922
Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#538537}
[modify] https://crrev.com/688c0d5295aabfafb7dc192cb1729fc3d8552527/ios/chrome/DEPS
[modify] https://crrev.com/688c0d5295aabfafb7dc192cb1729fc3d8552527/ios/chrome/browser/ssl/BUILD.gn
[modify] https://crrev.com/688c0d5295aabfafb7dc192cb1729fc3d8552527/ios/chrome/browser/ssl/captive_portal_detector_tab_helper.h
[modify] https://crrev.com/688c0d5295aabfafb7dc192cb1729fc3d8552527/ios/chrome/browser/ssl/captive_portal_detector_tab_helper.mm
[modify] https://crrev.com/688c0d5295aabfafb7dc192cb1729fc3d8552527/ios/chrome/browser/ssl/ios_ssl_error_handler_unittest.mm

Project Member

Comment 46 by bugdroid1@chromium.org, Mar 9 2018

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/1f2fb3734a11ef572cc24d471deee3b9a1b168e3

commit 1f2fb3734a11ef572cc24d471deee3b9a1b168e3
Author: Matt Menke <mmenke@chromium.org>
Date: Fri Mar 09 19:14:47 2018

NetworkService + iOS:  Use a NetworkContext to make URLLoaderFactories.

This will let use remove the use of URLRequestContextGetters in the
NetworkService, and also let us adjust URLLoaderFactory lifetime to
so that it lives as long as it has a live URLLoader, so it can own
shared objects.

Bug:  803149 
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo;master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I7028886f9df671530ee9863f80dc437adc20cdfb
Reviewed-on: https://chromium-review.googlesource.com/952342
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
Reviewed-by: Eugene But <eugenebut@chromium.org>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542188}
[modify] https://crrev.com/1f2fb3734a11ef572cc24d471deee3b9a1b168e3/ios/chrome/browser/browser_state/BUILD.gn
[modify] https://crrev.com/1f2fb3734a11ef572cc24d471deee3b9a1b168e3/ios/web/DEPS
[modify] https://crrev.com/1f2fb3734a11ef572cc24d471deee3b9a1b168e3/ios/web/browser_state.mm
[modify] https://crrev.com/1f2fb3734a11ef572cc24d471deee3b9a1b168e3/ios/web/public/BUILD.gn
[modify] https://crrev.com/1f2fb3734a11ef572cc24d471deee3b9a1b168e3/ios/web/public/DEPS
[modify] https://crrev.com/1f2fb3734a11ef572cc24d471deee3b9a1b168e3/ios/web/public/browser_state.h
[modify] https://crrev.com/1f2fb3734a11ef572cc24d471deee3b9a1b168e3/services/network/public/cpp/BUILD.gn

Status: Fixed (was: Assigned)
I guess this should be considered fixed now?

Sign in to add a comment