Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(907)

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 112203003: Fix renderer crashes when frame gets detached while injectng user scripts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Defer frame destruction until event loop. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/render_frame_impl.h" 5 #include "content/renderer/render_frame_impl.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/debug/alias.h" 11 #include "base/debug/alias.h"
12 #include "base/debug/dump_without_crashing.h" 12 #include "base/debug/dump_without_crashing.h"
13 #include "base/i18n/char_iterator.h" 13 #include "base/i18n/char_iterator.h"
14 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
15 #include "base/process/kill.h" 16 #include "base/process/kill.h"
16 #include "base/process/process.h" 17 #include "base/process/process.h"
17 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
18 #include "base/time/time.h" 19 #include "base/time/time.h"
19 #include "content/child/appcache/appcache_dispatcher.h" 20 #include "content/child/appcache/appcache_dispatcher.h"
20 #include "content/child/plugin_messages.h" 21 #include "content/child/plugin_messages.h"
21 #include "content/child/quota_dispatcher.h" 22 #include "content/child/quota_dispatcher.h"
22 #include "content/child/request_extra_data.h" 23 #include "content/child/request_extra_data.h"
23 #include "content/child/service_worker/web_service_worker_provider_impl.h" 24 #include "content/child/service_worker/web_service_worker_provider_impl.h"
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 // containing RenderViewHost (so that they have the same lifetime), so only 1038 // containing RenderViewHost (so that they have the same lifetime), so only
1038 // removal from the map is needed and no deletion. 1039 // removal from the map is needed and no deletion.
1039 FrameMap::iterator it = g_frame_map.Get().find(frame); 1040 FrameMap::iterator it = g_frame_map.Get().find(frame);
1040 CHECK(it != g_frame_map.Get().end()); 1041 CHECK(it != g_frame_map.Get().end());
1041 CHECK_EQ(it->second, this); 1042 CHECK_EQ(it->second, this);
1042 g_frame_map.Get().erase(it); 1043 g_frame_map.Get().erase(it);
1043 1044
1044 if (is_subframe) 1045 if (is_subframe)
1045 frame->parent()->removeChild(frame); 1046 frame->parent()->removeChild(frame);
1046 1047
1047 // |frame| is invalid after here. 1048 // We might detach frame as a result of observer actions. Defer closing
1048 frame->close(); 1049 // of frame until event loop so that observer still have valid frame object.
1050 base::MessageLoop::current()->PostTask(
1051 FROM_HERE,
1052 base::Bind(&RenderFrameImpl::closeFrame, frame));
dcheng 2014/02/26 19:37:23 We can simplify this slightly: base::Bind(&WebFram
1049 1053
1050 if (is_subframe) { 1054 if (is_subframe) {
1051 delete this; 1055 delete this;
1052 // Object is invalid after this point. 1056 // Object is invalid after this point.
1053 } 1057 }
1054 } 1058 }
1055 1059
1060 // static
1061 void RenderFrameImpl::closeFrame(blink::WebFrame* frame) {
1062 // |frame| is invalid after here.
1063 frame->close();
1064 }
1065
1056 void RenderFrameImpl::willClose(blink::WebFrame* frame) { 1066 void RenderFrameImpl::willClose(blink::WebFrame* frame) {
1057 // Call back to RenderViewImpl for observers to be notified. 1067 // Call back to RenderViewImpl for observers to be notified.
1058 // TODO(nasko): Remove once we have RenderFrameObserver. 1068 // TODO(nasko): Remove once we have RenderFrameObserver.
1059 render_view_->willClose(frame); 1069 render_view_->willClose(frame);
1060 } 1070 }
1061 1071
1062 void RenderFrameImpl::didChangeName(blink::WebFrame* frame, 1072 void RenderFrameImpl::didChangeName(blink::WebFrame* frame,
1063 const blink::WebString& name) { 1073 const blink::WebString& name) {
1064 if (!render_view_->renderer_preferences_.report_frame_name_changes) 1074 if (!render_view_->renderer_preferences_.report_frame_name_changes)
1065 return; 1075 return;
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
1450 // frame->tree()->top(). 1460 // frame->tree()->top().
1451 if (frame == render_view_->webview()->mainFrame()) { 1461 if (frame == render_view_->webview()->mainFrame()) {
1452 render_view_->Send(new ViewHostMsg_DocumentAvailableInMainFrame( 1462 render_view_->Send(new ViewHostMsg_DocumentAvailableInMainFrame(
1453 render_view_->GetRoutingID())); 1463 render_view_->GetRoutingID()));
1454 } 1464 }
1455 } 1465 }
1456 1466
1457 // Call back to RenderViewImpl for observers to be notified. 1467 // Call back to RenderViewImpl for observers to be notified.
1458 // TODO(nasko): Remove once we have RenderFrameObserver. 1468 // TODO(nasko): Remove once we have RenderFrameObserver.
1459 render_view_->didCreateDocumentElement(frame); 1469 render_view_->didCreateDocumentElement(frame);
1470 // Above code will call RenderViewObservers which can run Javascript that
1471 // removes |frame|. If this frame was subframe it will get destroyed
1472 // synchronously together with this object.
1460 } 1473 }
1461 1474
1462 void RenderFrameImpl::didReceiveTitle(blink::WebFrame* frame, 1475 void RenderFrameImpl::didReceiveTitle(blink::WebFrame* frame,
1463 const blink::WebString& title, 1476 const blink::WebString& title,
1464 blink::WebTextDirection direction) { 1477 blink::WebTextDirection direction) {
1465 // TODO(nasko): Investigate wheather implementation should move here. 1478 // TODO(nasko): Investigate wheather implementation should move here.
1466 render_view_->didReceiveTitle(frame, title, direction); 1479 render_view_->didReceiveTitle(frame, title, direction);
1467 } 1480 }
1468 1481
1469 void RenderFrameImpl::didChangeIcon(blink::WebFrame* frame, 1482 void RenderFrameImpl::didChangeIcon(blink::WebFrame* frame,
1470 blink::WebIconURL::Type icon_type) { 1483 blink::WebIconURL::Type icon_type) {
1471 // TODO(nasko): Investigate wheather implementation should move here. 1484 // TODO(nasko): Investigate wheather implementation should move here.
1472 render_view_->didChangeIcon(frame, icon_type); 1485 render_view_->didChangeIcon(frame, icon_type);
1473 } 1486 }
1474 1487
1475 void RenderFrameImpl::didFinishDocumentLoad(blink::WebFrame* frame) { 1488 void RenderFrameImpl::didFinishDocumentLoad(blink::WebFrame* frame) {
1476 WebDataSource* ds = frame->dataSource(); 1489 WebDataSource* ds = frame->dataSource();
1477 DocumentState* document_state = DocumentState::FromDataSource(ds); 1490 DocumentState* document_state = DocumentState::FromDataSource(ds);
1478 document_state->set_finish_document_load_time(Time::Now()); 1491 document_state->set_finish_document_load_time(Time::Now());
1479 1492
1480 Send( 1493 Send(
1481 new FrameHostMsg_DidFinishDocumentLoad(routing_id_, frame->identifier())); 1494 new FrameHostMsg_DidFinishDocumentLoad(routing_id_, frame->identifier()));
1482 1495
1483 // Call back to RenderViewImpl for observers to be notified. 1496 // Call back to RenderViewImpl for observers to be notified.
1484 // TODO(nasko): Remove once we have RenderFrameObserver for this method. 1497 // TODO(nasko): Remove once we have RenderFrameObserver for this method.
1485 render_view_->didFinishDocumentLoad(frame); 1498 render_view_->didFinishDocumentLoad(frame);
1486 1499
1487 // Check whether we have new encoding name. 1500 // Above code will call RenderViewObservers which can run Javascript that
1488 render_view_->UpdateEncoding(frame, frame->view()->pageEncoding().utf8()); 1501 // removes |frame|. If this frame was subframe it will get destroyed
1502 // synchronously together with this object.
1503 if (frame->view()) {
1504 // Check whether we have new encoding name.
1505 render_view_->UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
1506 }
1489 } 1507 }
1490 1508
1491 void RenderFrameImpl::didHandleOnloadEvents(blink::WebFrame* frame) { 1509 void RenderFrameImpl::didHandleOnloadEvents(blink::WebFrame* frame) {
1492 // TODO(nasko): Move implementation here. Needed state: 1510 // TODO(nasko): Move implementation here. Needed state:
1493 // * page_id_ 1511 // * page_id_
1494 render_view_->didHandleOnloadEvents(frame); 1512 render_view_->didHandleOnloadEvents(frame);
1495 } 1513 }
1496 1514
1497 void RenderFrameImpl::didFailLoad(blink::WebFrame* frame, 1515 void RenderFrameImpl::didFailLoad(blink::WebFrame* frame,
1498 const blink::WebURLError& error) { 1516 const blink::WebURLError& error) {
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
2212 2230
2213 void RenderFrameImpl::didStartLoading() { 2231 void RenderFrameImpl::didStartLoading() {
2214 Send(new FrameHostMsg_DidStartLoading(routing_id_)); 2232 Send(new FrameHostMsg_DidStartLoading(routing_id_));
2215 } 2233 }
2216 2234
2217 void RenderFrameImpl::didStopLoading() { 2235 void RenderFrameImpl::didStopLoading() {
2218 Send(new FrameHostMsg_DidStopLoading(routing_id_)); 2236 Send(new FrameHostMsg_DidStopLoading(routing_id_));
2219 } 2237 }
2220 2238
2221 } // namespace content 2239 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698