blob: a48d549e591436e6f5bd11cb6941baeb7be65d31 [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"
[email protected]47752982014-07-29 08:01:4317#include "cc/base/switches.h"
[email protected]8bf1048012012-02-08 01:22:1818#include "content/browser/gpu/gpu_process_host_ui_shim.h"
[email protected]029bd942013-01-22 08:30:3319#include "content/public/browser/browser_thread.h"
[email protected]73270292013-08-09 03:48:0720#include "content/public/common/content_constants.h"
[email protected]8bf1048012012-02-08 01:22:1821#include "content/public/common/url_constants.h"
[email protected]029bd942013-01-22 08:30:3322#include "ppapi/proxy/ppapi_messages.h"
[email protected]707e1c42013-07-09 21:18:5823#include "url/gurl.h"
[email protected]8bf1048012012-02-08 01:22:1824
thestigc4cac8f2014-09-04 21:17:5025#if defined(ENABLE_PLUGINS)
26#include "content/browser/ppapi_plugin_process_host.h"
27#endif
28
[email protected]8bf1048012012-02-08 01:22:1829namespace content {
30
[email protected]029bd942013-01-22 08:30:3331namespace {
32
[email protected]b4b34792014-06-14 08:29:3733// Define the Asan debug URLs.
34const char kAsanCrashDomain[] = "crash";
35const char kAsanHeapOverflow[] = "/browser-heap-overflow";
36const char kAsanHeapUnderflow[] = "/browser-heap-underflow";
37const char kAsanUseAfterFree[] = "/browser-use-after-free";
38#if defined(SYZYASAN)
39const char kAsanCorruptHeapBlock[] = "/browser-corrupt-heap-block";
40const char kAsanCorruptHeap[] = "/browser-corrupt-heap";
erikwright420a0902015-02-26 21:16:1741
42// Define the Kasko debug URLs.
43const char kKaskoCrashDomain[] = "kasko";
44const char kKaskoSendReport[] = "/send-report";
[email protected]b4b34792014-06-14 08:29:3745#endif
46
[email protected]029bd942013-01-22 08:30:3347void HandlePpapiFlashDebugURL(const GURL& url) {
48#if defined(ENABLE_PLUGINS)
[email protected]f8a6d732013-03-02 22:46:0349 bool crash = url == GURL(kChromeUIPpapiFlashCrashURL);
[email protected]029bd942013-01-22 08:30:3350
51 std::vector<PpapiPluginProcessHost*> hosts;
[email protected]32956122013-12-25 07:29:2452 PpapiPluginProcessHost::FindByName(
53 base::UTF8ToUTF16(kFlashPluginName), &hosts);
[email protected]029bd942013-01-22 08:30:3354 for (std::vector<PpapiPluginProcessHost*>::iterator iter = hosts.begin();
55 iter != hosts.end(); ++iter) {
56 if (crash)
57 (*iter)->Send(new PpapiMsg_Crash());
58 else
59 (*iter)->Send(new PpapiMsg_Hang());
60 }
61#endif
62}
63
erikwright420a0902015-02-26 21:16:1764bool IsKaskoDebugURL(const GURL& url) {
65#if defined(SYZYASAN)
66 return (url.is_valid() && url.SchemeIs(kChromeUIScheme) &&
67 url.DomainIs(kKaskoCrashDomain, sizeof(kKaskoCrashDomain) - 1) &&
68 url.path() == kKaskoSendReport);
69#else
70 return false;
71#endif
72}
73
74void HandleKaskoDebugURL() {
75#if defined(SYZYASAN)
76 // Signature of an enhanced crash reporting function.
77 typedef void(__cdecl * ReportCrashWithProtobufPtr)(EXCEPTION_POINTERS*,
78 const char*);
79
80 HMODULE exe_hmodule = ::GetModuleHandle(NULL);
81 ReportCrashWithProtobufPtr report_crash_with_protobuf =
82 reinterpret_cast<ReportCrashWithProtobufPtr>(
83 ::GetProcAddress(exe_hmodule, "ReportCrashWithProtobuf"));
84 if (report_crash_with_protobuf)
85 report_crash_with_protobuf(NULL, "Invoked from debug url.");
86 else
87 NOTREACHED();
88#else
89 NOTIMPLEMENTED();
90#endif
91}
92
[email protected]b4b34792014-06-14 08:29:3793bool IsAsanDebugURL(const GURL& url) {
94#if defined(SYZYASAN)
95 if (!base::debug::IsBinaryInstrumented())
96 return false;
97#endif
98
99 if (!(url.is_valid() && url.SchemeIs(kChromeUIScheme) &&
100 url.DomainIs(kAsanCrashDomain, sizeof(kAsanCrashDomain) - 1) &&
101 url.has_path())) {
102 return false;
103 }
104
105 if (url.path() == kAsanHeapOverflow || url.path() == kAsanHeapUnderflow ||
106 url.path() == kAsanUseAfterFree) {
107 return true;
108 }
109
110#if defined(SYZYASAN)
111 if (url.path() == kAsanCorruptHeapBlock || url.path() == kAsanCorruptHeap)
112 return true;
113#endif
114
115 return false;
116}
117
118bool HandleAsanDebugURL(const GURL& url) {
119#if defined(SYZYASAN)
120 if (!base::debug::IsBinaryInstrumented())
121 return false;
122
123 if (url.path() == kAsanCorruptHeapBlock) {
124 base::debug::AsanCorruptHeapBlock();
125 return true;
126 } else if (url.path() == kAsanCorruptHeap) {
127 base::debug::AsanCorruptHeap();
128 return true;
129 }
130#endif
131
132#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
133 if (url.path() == kAsanHeapOverflow) {
134 base::debug::AsanHeapOverflow();
135 } else if (url.path() == kAsanHeapUnderflow) {
136 base::debug::AsanHeapUnderflow();
137 } else if (url.path() == kAsanUseAfterFree) {
138 base::debug::AsanHeapUseAfterFree();
139 } else {
140 return false;
141 }
142#endif
143
144 return true;
145}
146
147
[email protected]029bd942013-01-22 08:30:33148} // namespace
149
Sylvain Defresnec6ccc77d2014-09-19 10:19:35150bool HandleDebugURL(const GURL& url, ui::PageTransition transition) {
[email protected]47752982014-07-29 08:01:43151 // Ensure that the user explicitly navigated to this URL, unless
152 // kEnableGpuBenchmarking is enabled by Telemetry.
[email protected]479278702014-08-11 20:32:09153 bool is_telemetry_navigation =
154 base::CommandLine::ForCurrentProcess()->HasSwitch(
155 cc::switches::kEnableGpuBenchmarking) &&
Sylvain Defresnec6ccc77d2014-09-19 10:19:35156 (transition & ui::PAGE_TRANSITION_TYPED);
[email protected]8bf1048012012-02-08 01:22:18157
Sylvain Defresnec6ccc77d2014-09-19 10:19:35158 if (!(transition & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR) &&
[email protected]47752982014-07-29 08:01:43159 !is_telemetry_navigation)
160 return false;
[email protected]eabfe1912014-05-12 10:07:28161
[email protected]b4b34792014-06-14 08:29:37162 if (IsAsanDebugURL(url))
163 return HandleAsanDebugURL(url);
164
erikwright420a0902015-02-26 21:16:17165 if (IsKaskoDebugURL(url)) {
166 HandleKaskoDebugURL();
167 return true;
168 }
169
avi861ff752014-09-23 22:55:33170 if (url == GURL(kChromeUIBrowserCrashURL)) {
[email protected]8bf1048012012-02-08 01:22:18171 // Induce an intentional crash in the browser process.
172 CHECK(false);
173 return true;
174 }
175
[email protected]f8a6d732013-03-02 22:46:03176 if (url == GURL(kChromeUIGpuCleanURL)) {
[email protected]8bf1048012012-02-08 01:22:18177 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
178 if (shim)
179 shim->SimulateRemoveAllContext();
180 return true;
181 }
182
[email protected]f8a6d732013-03-02 22:46:03183 if (url == GURL(kChromeUIGpuCrashURL)) {
[email protected]8bf1048012012-02-08 01:22:18184 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
185 if (shim)
186 shim->SimulateCrash();
187 return true;
188 }
189
[email protected]f8a6d732013-03-02 22:46:03190 if (url == GURL(kChromeUIGpuHangURL)) {
[email protected]8bf1048012012-02-08 01:22:18191 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance();
192 if (shim)
193 shim->SimulateHang();
194 return true;
195 }
196
[email protected]f8a6d732013-03-02 22:46:03197 if (url == GURL(kChromeUIPpapiFlashCrashURL) ||
198 url == GURL(kChromeUIPpapiFlashHangURL)) {
[email protected]029bd942013-01-22 08:30:33199 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
200 base::Bind(&HandlePpapiFlashDebugURL, url));
201 return true;
202 }
203
[email protected]8bf1048012012-02-08 01:22:18204 return false;
205}
206
[email protected]c02f1ba2014-02-03 06:53:53207bool IsRendererDebugURL(const GURL& url) {
208 if (!url.is_valid())
209 return false;
210
[email protected]cca6f392014-05-28 21:32:26211 if (url.SchemeIs(url::kJavaScriptScheme))
[email protected]c02f1ba2014-02-03 06:53:53212 return true;
213
214 return url == GURL(kChromeUICrashURL) ||
[email protected]f0e90cf92014-07-21 17:13:58215 url == GURL(kChromeUIDumpURL) ||
[email protected]c02f1ba2014-02-03 06:53:53216 url == GURL(kChromeUIKillURL) ||
217 url == GURL(kChromeUIHangURL) ||
218 url == GURL(kChromeUIShorthangURL);
219}
220
[email protected]8bf1048012012-02-08 01:22:18221} // namespace content