I've found the problem - BlinkTestController::layout_test_control_map_ uses |RenderProcessHost*| as a key and the address gets reused:
...
[213970:213970:0820/133938.422694:ERROR:blink_test_controller.cc(1277)] BlinkTestController::GetLayoutTestControlPtr; no ControlPtr yet; frame = 0xe32cdafe900; frame->GetProcess()->GetID() = 6
[213970:213970:0820/133938.422768:ERROR:blink_test_controller.cc(1289)] BlinkTestController::GetLayoutTestControlPtr; returning...; layout_test_control_map_[frame].get() = 0xe32cdc4c470; frame = 0xe32cdafe900; frame->GetProcess()->GetID() = 6
...
[213970:213970:0820/133938.566095:ERROR:blink_test_controller.cc(1289)] BlinkTestController::GetLayoutTestControlPtr; returning...; layout_test_control_map_[frame].get() = 0xe32cdc4c470; frame = 0xe32cdafe900; frame->GetProcess()->GetID() = 7
...
Same |frame| address, different |frame->GetProcess()->GetID()|. Ooops. I guess I can only blame myself for not catching this during code review at https://codereview.chromium.org/2594913002...
+author and other reviewers of https://codereview.chromium.org/2594913002 to point out that:
- Using |RenderFrameHost*| as a map key is risky. Using a pair of (process id, frame routing id) is more obviously correct.
- interface_using_frame_pipe_ptr.set_connection_error_handler(EraseMapElement) doesn't help, because there is a delay between 1) destroying RenderFrameHost and 2) actually running EraseMapElement. This seems similar to the problem in https://docs.google.com/document/d/1pu-VjoQiPK4w7N04-bMBBKODnqZGb4QHZNuoYgzMU9A
Comment 1 by bugdroid1@chromium.org
, Apr 18 2018