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
3 // found in the LICENSE file.
5 #include "content/browser/frame_host/debug_urls.h"
9 #include "base/command_line.h"
10 #include "base/debug/asan_invalid_access.h"
11 #include "base/debug/profiler.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "cc/base/switches.h"
14 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/common/content_constants.h"
17 #include "content/public/common/url_constants.h"
18 #include "ppapi/proxy/ppapi_messages.h"
21 #if defined(ENABLE_PLUGINS)
22 #include "content/browser/ppapi_plugin_process_host.h"
29 // Define the Asan debug URLs.
30 const char kAsanCrashDomain
[] = "crash";
31 const char kAsanHeapOverflow
[] = "/browser-heap-overflow";
32 const char kAsanHeapUnderflow
[] = "/browser-heap-underflow";
33 const char kAsanUseAfterFree
[] = "/browser-use-after-free";
35 const char kAsanCorruptHeapBlock
[] = "/browser-corrupt-heap-block";
36 const char kAsanCorruptHeap
[] = "/browser-corrupt-heap";
39 void HandlePpapiFlashDebugURL(const GURL
& url
) {
40 #if defined(ENABLE_PLUGINS)
41 bool crash
= url
== GURL(kChromeUIPpapiFlashCrashURL
);
43 std::vector
<PpapiPluginProcessHost
*> hosts
;
44 PpapiPluginProcessHost::FindByName(
45 base::UTF8ToUTF16(kFlashPluginName
), &hosts
);
46 for (std::vector
<PpapiPluginProcessHost
*>::iterator iter
= hosts
.begin();
47 iter
!= hosts
.end(); ++iter
) {
49 (*iter
)->Send(new PpapiMsg_Crash());
51 (*iter
)->Send(new PpapiMsg_Hang());
56 bool IsAsanDebugURL(const GURL
& url
) {
58 if (!base::debug::IsBinaryInstrumented())
62 if (!(url
.is_valid() && url
.SchemeIs(kChromeUIScheme
) &&
63 url
.DomainIs(kAsanCrashDomain
, sizeof(kAsanCrashDomain
) - 1) &&
68 if (url
.path() == kAsanHeapOverflow
|| url
.path() == kAsanHeapUnderflow
||
69 url
.path() == kAsanUseAfterFree
) {
74 if (url
.path() == kAsanCorruptHeapBlock
|| url
.path() == kAsanCorruptHeap
)
81 bool HandleAsanDebugURL(const GURL
& url
) {
83 if (!base::debug::IsBinaryInstrumented())
86 if (url
.path() == kAsanCorruptHeapBlock
) {
87 base::debug::AsanCorruptHeapBlock();
89 } else if (url
.path() == kAsanCorruptHeap
) {
90 base::debug::AsanCorruptHeap();
95 #if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
96 if (url
.path() == kAsanHeapOverflow
) {
97 base::debug::AsanHeapOverflow();
98 } else if (url
.path() == kAsanHeapUnderflow
) {
99 base::debug::AsanHeapUnderflow();
100 } else if (url
.path() == kAsanUseAfterFree
) {
101 base::debug::AsanHeapUseAfterFree();
113 bool HandleDebugURL(const GURL
& url
, PageTransition transition
) {
114 // Ensure that the user explicitly navigated to this URL, unless
115 // kEnableGpuBenchmarking is enabled by Telemetry.
116 bool is_telemetry_navigation
=
117 base::CommandLine::ForCurrentProcess()->HasSwitch(
118 cc::switches::kEnableGpuBenchmarking
) &&
119 (transition
& PAGE_TRANSITION_TYPED
);
121 if (!(transition
& PAGE_TRANSITION_FROM_ADDRESS_BAR
) &&
122 !is_telemetry_navigation
)
125 if (IsAsanDebugURL(url
))
126 return HandleAsanDebugURL(url
);
128 if (url
.host() == kChromeUIBrowserCrashHost
) {
129 // Induce an intentional crash in the browser process.
134 if (url
== GURL(kChromeUIGpuCleanURL
)) {
135 GpuProcessHostUIShim
* shim
= GpuProcessHostUIShim::GetOneInstance();
137 shim
->SimulateRemoveAllContext();
141 if (url
== GURL(kChromeUIGpuCrashURL
)) {
142 GpuProcessHostUIShim
* shim
= GpuProcessHostUIShim::GetOneInstance();
144 shim
->SimulateCrash();
148 if (url
== GURL(kChromeUIGpuHangURL
)) {
149 GpuProcessHostUIShim
* shim
= GpuProcessHostUIShim::GetOneInstance();
151 shim
->SimulateHang();
155 if (url
== GURL(kChromeUIPpapiFlashCrashURL
) ||
156 url
== GURL(kChromeUIPpapiFlashHangURL
)) {
157 BrowserThread::PostTask(BrowserThread::IO
, FROM_HERE
,
158 base::Bind(&HandlePpapiFlashDebugURL
, url
));
165 bool IsRendererDebugURL(const GURL
& url
) {
169 if (url
.SchemeIs(url::kJavaScriptScheme
))
172 return url
== GURL(kChromeUICrashURL
) ||
173 url
== GURL(kChromeUIDumpURL
) ||
174 url
== GURL(kChromeUIKillURL
) ||
175 url
== GURL(kChromeUIHangURL
) ||
176 url
== GURL(kChromeUIShorthangURL
);
179 } // namespace content