blob: 8459559b1e1764a1167b7217b99d1c06e0722944 [file] [log] [blame]
[email protected]d4a8ca482013-10-30 21:06:401// Copyright 2013 The Chromium Authors. All rights reserved.
[email protected]8bf1048012012-02-08 01:22:182// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]d4a8ca482013-10-30 21:06:405#include "content/browser/frame_host/debug_urls.h"
[email protected]8bf1048012012-02-08 01:22:186
erikwright420a0902015-02-26 21:16:177#if defined(SYZYASAN)
8#include <windows.h>
9#endif
10
[email protected]029bd942013-01-22 08:30:3311#include <vector>
12
[email protected]47752982014-07-29 08:01:4313#include "base/command_line.h"
[email protected]b4b34792014-06-14 08:29:3714#include "base/debug/asan_invalid_access.h"
15#include "base/debug/profiler.h"
[email protected]74ebfb12013-06-07 20:48:0016#include "base/strings/utf_string_conversions.h"
erikwright811f1b02015-04-17 18:58:3617#include "base/synchronization/waitable_event.h"
erikwrightcf61cd792015-04-23 14:35:2018#include "base/threading/thread_restrictions.h"
[email protected]47752982014-07-29 08:01:4319#include "cc/base/switches.h"
[email protected]8bf1048012012-02-08 01:22:1820#include "content/browser/gpu/gpu_process_host_ui_shim.h"
[email protected]029bd942013-01-22 08:30:3321#include "content/public/browser/browser_thread.h"
[email protected]73270292013-08-09 03:48:0722#include "content/public/common/content_constants.h"
[email protected]8bf1048012012-02-08 01:22:1823#include "content/public/common/url_constants.h"
[email protected]029bd942013-01-22 08:30:3324#include "ppapi/proxy/ppapi_messages.h"
[email protected]707e1c42013-07-09 21:18:5825#include "url/gurl.h"
[email protected]8bf1048012012-02-08 01:22:1826
thestigc4cac8f2014-09-04 21:17:5027#if defined(ENABLE_PLUGINS)
28#include "content/browser/ppapi_plugin_process_host.h"
29#endif
30
[email protected]8bf1048012012-02-08 01:22:1831namespace content {
32
[email protected]029bd942013-01-22 08:30:3333namespace {
34
[email protected]b4b34792014-06-14 08:29:3735// Define the Asan debug URLs.
36const char kAsanCrashDomain[] = "crash";
37const char kAsanHeapOverflow[] = "/browser-heap-overflow";
38const char kAsanHeapUnderflow[] = "/browser-heap-underflow";
39const char kAsanUseAfterFree[] = "/browser-use-after-free";
40#if defined(SYZYASAN)
41const char kAsanCorruptHeapBlock[] = "/browser-corrupt-heap-block";
42const char kAsanCorruptHeap[] = "/browser-corrupt-heap";
erikwright3d483052015-03-06 13:14:4443#endif
erikwright420a0902015-02-26 21:16:1744
erikwright3d483052015-03-06 13:14:4445#if defined(KASKO)
erikwright420a0902015-02-26 21:16:1746// Define the Kasko debug URLs.
47const char kKaskoCrashDomain[] = "kasko";
48const char kKaskoSendReport[] = "/send-report";
[email protected]b4b34792014-06-14 08:29:3749#endif
50
[email protected]029bd942013-01-22 08:30:3351void HandlePpapiFlashDebugURL(const GURL& url) {
52#if defined(ENABLE_PLUGINS)
[email protected]f8a6d732013-03-02 22:46:0353 bool crash = url == GURL(kChromeUIPpapiFlashCrashURL);
[email protected]029bd942013-01-22 08:30:3354
55 std::vector<PpapiPluginProcessHost*> hosts;
[email protected]32956122013-12-25 07:29:2456 PpapiPluginProcessHost::FindByName(
57 base::UTF8ToUTF16(kFlashPluginName), &hosts);
[email protected]029bd942013-01-22 08:30:3358 for (std::vector<PpapiPluginProcessHost*>::iterator iter = hosts.begin();
59 iter != hosts.end(); ++iter) {
60 if (crash)
61 (*iter)->Send(new PpapiMsg_Crash());
62 else
63 (*iter)->Send(new PpapiMsg_Hang());
64 }
65#endif
66}
67
erikwright420a0902015-02-26 21:16:1768bool IsKaskoDebugURL(const GURL& url) {
erikwright3d483052015-03-06 13:14:4469#if defined(KASKO)
erikwright420a0902015-02-26 21:16:1770 return (url.is_valid() && url.SchemeIs(kChromeUIScheme) &&
qyearsley7ffaa682015-08-03 07:03:4971 url.DomainIs(kKaskoCrashDomain) &&
erikwright420a0902015-02-26 21:16:1772 url.path() == kKaskoSendReport);
73#else
74 return false;
75#endif
76}
77
78void HandleKaskoDebugURL() {
erikwright3d483052015-03-06 13:14:4479#if defined(KASKO)
erikwright420a0902015-02-26 21:16:1780 // Signature of an enhanced crash reporting function.
81 typedef void(__cdecl * ReportCrashWithProtobufPtr)(EXCEPTION_POINTERS*,
82 const char*);
83
84 HMODULE exe_hmodule = ::GetModuleHandle(NULL);
85 ReportCrashWithProtobufPtr report_crash_with_protobuf =
86 reinterpret_cast<ReportCrashWithProtobufPtr>(
87 ::GetProcAddress(exe_hmodule, "ReportCrashWithProtobuf"));
88 if (report_crash_with_protobuf)
89 report_crash_with_protobuf(NULL, "Invoked from debug url.");
90 else
91 NOTREACHED();
92#else
93 NOTIMPLEMENTED();
94#endif
95}
96
[email protected]b4b34792014-06-14 08:29:3797bool IsAsanDebugURL(const GURL& url) {
98#if defined(SYZYASAN)
99 if (!base::debug::IsBinaryInstrumented())
100 return false;
101#endif
102
103 if (!(url.is_valid() && url.SchemeIs(kChromeUIScheme) &&
qyearsley7ffaa682015-08-03 07:03:49104 url.DomainIs(kAsanCrashDomain) &&
[email protected]b4b34792014-06-14 08:29:37105 url.has_path())) {
106 return false;
107 }
108
109 if (url.path() == kAsanHeapOverflow || url.path() == kAsanHeapUnderflow ||
110 url.path() == kAsanUseAfterFree) {
111 return true;
112 }
113
114#if defined(SYZYASAN)
115 if (url.path() == kAsanCorruptHeapBlock || url.path() == kAsanCorruptHeap)
116 return true;
117#endif
118
119 return false;
120}
121
122bool HandleAsanDebugURL(const GURL& url) {
123#if defined(SYZYASAN)
124 if (!base::debug::IsBinaryInstrumented())
125 return false;
126
127 if (url.path() == kAsanCorruptHeapBlock) {
128 base::debug::AsanCorruptHeapBlock();
129 return true;
130 } else if (url.path() == kAsanCorruptHeap) {
131 base::debug::AsanCorruptHeap();
132 return true;
133 }
134#endif
135
136#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
137 if (url.path() == kAsanHeapOverflow) {
138 base::debug::AsanHeapOverflow();
139 } else if (url.path() == kAsanHeapUnderflow) {
140 base::debug::AsanHeapUnderflow();
141 } else if (url.path() == kAsanUseAfterFree) {
142 base::debug::AsanHeapUseAfterFree();
143 } else {
144 return false;
145 }
146#endif
147
148 return true;
149}
150
151
[email protected]029bd942013-01-22 08:30:33152} // namespace
153
erikwrightcf61cd792015-04-23 14:35:20154class ScopedAllowWaitForDebugURL {
155 private:
156 base::ThreadRestrictions::ScopedAllowWait wait;
157};
158
Sylvain Defresnec6ccc77d2014-09-19 10:19:35159bool HandleDebugURL(const GURL& url, ui::PageTransition transition) {
[email protected]47752982014-07-29 08:01:43160 // Ensure that the user explicitly navigated to this URL, unless
161 // kEnableGpuBenchmarking is enabled by Telemetry.
[email protected]479278702014-08-11 20:32:09162 bool is_telemetry_navigation =
163 base::CommandLine::ForCurrentProcess()->HasSwitch(
164 cc::switches::kEnableGpuBenchmarking) &&
vmiura20fa51a32015-10-27 21:39:34165 (PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED));
[email protected]8bf1048012012-02-08 01:22:18166
Sylvain Defresnec6ccc77d2014-09-19 10:19:35167 if (!(transition & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) &&
[email protected]47752982014-07-29 08:01:43168 !is_telemetry_navigation)
169 return false;
[email protected]eabfe1912014-05-12 10:07:28170
[email protected]b4b34792014-06-14 08:29:37171 if (IsAsanDebugURL(url))
172 return HandleAsanDebugURL(url);
173
erikwright420a0902015-02-26 21:16:17174 if (IsKaskoDebugURL(url)) {
175 HandleKaskoDebugURL();
176 return true;
177 }
178
avi861ff752014-09-23 22:55:33179 if (url == GURL(kChromeUIBrowserCrashURL)) {
[email protected]8bf1048012012-02-08 01:22:18180 // Induce an intentional crash in the browser process.
181 CHECK(false);
182 return true;
183 }
184
erikwright811f1b02015-04-17 18:58:36185 if (url == GURL(kChromeUIBrowserUIHang)) {
erikwrightcf61cd792015-04-23 14:35:20186 ScopedAllowWaitForDebugURL allow_wait;
erikwright811f1b02015-04-17 18:58:36187 base::WaitableEvent(false, false).Wait();
188 return true;
189 }
190
[email protected]f8a6d732013-03-02 22:46:03191 if (url == GURL(kChromeUIGpuCleanURL)) {
[email protected]8bf1048012012-02-08 01:22:18192 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
193 if (shim)
194 shim->SimulateRemoveAllContext();
195 return true;
196 }
197
[email protected]f8a6d732013-03-02 22:46:03198 if (url == GURL(kChromeUIGpuCrashURL)) {
[email protected]8bf1048012012-02-08 01:22:18199 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
200 if (shim)
201 shim->SimulateCrash();
202 return true;
203 }
204
[email protected]f8a6d732013-03-02 22:46:03205 if (url == GURL(kChromeUIGpuHangURL)) {
[email protected]8bf1048012012-02-08 01:22:18206 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
207 if (shim)
208 shim->SimulateHang();
209 return true;
210 }
211
[email protected]f8a6d732013-03-02 22:46:03212 if (url == GURL(kChromeUIPpapiFlashCrashURL) ||
213 url == GURL(kChromeUIPpapiFlashHangURL)) {
[email protected]029bd942013-01-22 08:30:33214 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
215 base::Bind(&HandlePpapiFlashDebugURL, url));
216 return true;
217 }
218
[email protected]8bf1048012012-02-08 01:22:18219 return false;
220}
221
[email protected]c02f1ba2014-02-03 06:53:53222bool IsRendererDebugURL(const GURL& url) {
223 if (!url.is_valid())
224 return false;
225
[email protected]cca6f392014-05-28 21:32:26226 if (url.SchemeIs(url::kJavaScriptScheme))
[email protected]c02f1ba2014-02-03 06:53:53227 return true;
228
pcc31843222015-07-31 00:46:30229 return url == GURL(kChromeUIBadCastCrashURL) ||
230 url == GURL(kChromeUICrashURL) ||
[email protected]f0e90cf92014-07-21 17:13:58231 url == GURL(kChromeUIDumpURL) ||
[email protected]c02f1ba2014-02-03 06:53:53232 url == GURL(kChromeUIKillURL) ||
233 url == GURL(kChromeUIHangURL) ||
234 url == GURL(kChromeUIShorthangURL);
235}
236
[email protected]8bf1048012012-02-08 01:22:18237} // namespace content