debug_urls.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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. 4 5#include "content/browser/frame_host/debug_urls.h" 6 7#include <vector> 8 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/browser/ppapi_plugin_process_host.h" 16#include "content/public/browser/browser_thread.h" 17#include "content/public/common/content_constants.h" 18#include "content/public/common/url_constants.h" 19#include "ppapi/proxy/ppapi_messages.h" 20#include "url/gurl.h" 21 22namespace content { 23 24namespace { 25 26// Define the Asan debug URLs. 27const char kAsanCrashDomain[] = "crash"; 28const char kAsanHeapOverflow[] = "/browser-heap-overflow"; 29const char kAsanHeapUnderflow[] = "/browser-heap-underflow"; 30const char kAsanUseAfterFree[] = "/browser-use-after-free"; 31#if defined(SYZYASAN) 32const char kAsanCorruptHeapBlock[] = "/browser-corrupt-heap-block"; 33const char kAsanCorruptHeap[] = "/browser-corrupt-heap"; 34#endif 35 36void HandlePpapiFlashDebugURL(const GURL& url) { 37#if defined(ENABLE_PLUGINS) 38 bool crash = url == GURL(kChromeUIPpapiFlashCrashURL); 39 40 std::vector<PpapiPluginProcessHost*> hosts; 41 PpapiPluginProcessHost::FindByName( 42 base::UTF8ToUTF16(kFlashPluginName), &hosts); 43 for (std::vector<PpapiPluginProcessHost*>::iterator iter = hosts.begin(); 44 iter != hosts.end(); ++iter) { 45 if (crash) 46 (*iter)->Send(new PpapiMsg_Crash()); 47 else 48 (*iter)->Send(new PpapiMsg_Hang()); 49 } 50#endif 51} 52 53bool IsAsanDebugURL(const GURL& url) { 54#if defined(SYZYASAN) 55 if (!base::debug::IsBinaryInstrumented()) 56 return false; 57#endif 58 59 if (!(url.is_valid() && url.SchemeIs(kChromeUIScheme) && 60 url.DomainIs(kAsanCrashDomain, sizeof(kAsanCrashDomain) - 1) && 61 url.has_path())) { 62 return false; 63 } 64 65 if (url.path() == kAsanHeapOverflow || url.path() == kAsanHeapUnderflow || 66 url.path() == kAsanUseAfterFree) { 67 return true; 68 } 69 70#if defined(SYZYASAN) 71 if (url.path() == kAsanCorruptHeapBlock || url.path() == kAsanCorruptHeap) 72 return true; 73#endif 74 75 return false; 76} 77 78bool HandleAsanDebugURL(const GURL& url) { 79#if defined(SYZYASAN) 80 if (!base::debug::IsBinaryInstrumented()) 81 return false; 82 83 if (url.path() == kAsanCorruptHeapBlock) { 84 base::debug::AsanCorruptHeapBlock(); 85 return true; 86 } else if (url.path() == kAsanCorruptHeap) { 87 base::debug::AsanCorruptHeap(); 88 return true; 89 } 90#endif 91 92#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN) 93 if (url.path() == kAsanHeapOverflow) { 94 base::debug::AsanHeapOverflow(); 95 } else if (url.path() == kAsanHeapUnderflow) { 96 base::debug::AsanHeapUnderflow(); 97 } else if (url.path() == kAsanUseAfterFree) { 98 base::debug::AsanHeapUseAfterFree(); 99 } else { 100 return false; 101 } 102#endif 103 104 return true; 105} 106 107 108} // namespace 109 110bool HandleDebugURL(const GURL& url, PageTransition transition) { 111 // Ensure that the user explicitly navigated to this URL, unless 112 // kEnableGpuBenchmarking is enabled by Telemetry. 113 bool is_telemetry_navigation = CommandLine::ForCurrentProcess()->HasSwitch( 114 cc::switches::kEnableGpuBenchmarking) && 115 (transition & PAGE_TRANSITION_TYPED); 116 117 if (!(transition & PAGE_TRANSITION_FROM_ADDRESS_BAR) && 118 !is_telemetry_navigation) 119 return false; 120 121 if (IsAsanDebugURL(url)) 122 return HandleAsanDebugURL(url); 123 124 if (url.host() == kChromeUIBrowserCrashHost) { 125 // Induce an intentional crash in the browser process. 126 CHECK(false); 127 return true; 128 } 129 130 if (url == GURL(kChromeUIGpuCleanURL)) { 131 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance(); 132 if (shim) 133 shim->SimulateRemoveAllContext(); 134 return true; 135 } 136 137 if (url == GURL(kChromeUIGpuCrashURL)) { 138 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance(); 139 if (shim) 140 shim->SimulateCrash(); 141 return true; 142 } 143 144 if (url == GURL(kChromeUIGpuHangURL)) { 145 GpuProcessHostUIShim* shim = GpuProcessHostUIShim::GetOneInstance(); 146 if (shim) 147 shim->SimulateHang(); 148 return true; 149 } 150 151 if (url == GURL(kChromeUIPpapiFlashCrashURL) || 152 url == GURL(kChromeUIPpapiFlashHangURL)) { 153 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 154 base::Bind(&HandlePpapiFlashDebugURL, url)); 155 return true; 156 } 157 158 return false; 159} 160 161bool IsRendererDebugURL(const GURL& url) { 162 if (!url.is_valid()) 163 return false; 164 165 if (url.SchemeIs(url::kJavaScriptScheme)) 166 return true; 167 168 return url == GURL(kChromeUICrashURL) || 169 url == GURL(kChromeUIDumpURL) || 170 url == GURL(kChromeUIKillURL) || 171 url == GURL(kChromeUIHangURL) || 172 url == GURL(kChromeUIShorthangURL); 173} 174 175} // namespace content 176