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

Side by Side Diff: webkit/tools/test_shell/test_shell_main.cc

Issue 3105: Enforce Terminate on Heap Corruption in most of our executable on Windows XP ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « webkit/tools/test_shell/run_all_tests.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 // Creates an instance of the test_shell. 5 // Creates an instance of the test_shell.
6 6
7 #include <stdlib.h> // required by _set_abort_behavior 7 #include <stdlib.h> // required by _set_abort_behavior
8 8
9 #include <windows.h> 9 #include <windows.h>
10 #include <commctrl.h> 10 #include <commctrl.h>
11 11
12 #include "base/at_exit.h" 12 #include "base/at_exit.h"
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/event_recorder.h" 15 #include "base/event_recorder.h"
16 #include "base/file_util.h" 16 #include "base/file_util.h"
17 #include "base/gfx/native_theme.h" 17 #include "base/gfx/native_theme.h"
18 #include "base/icu_util.h" 18 #include "base/icu_util.h"
19 #include "base/memory_debug.h" 19 #include "base/memory_debug.h"
20 #include "base/message_loop.h" 20 #include "base/message_loop.h"
21 #include "base/path_service.h" 21 #include "base/path_service.h"
22 #include "base/process_util.h"
22 #include "base/resource_util.h" 23 #include "base/resource_util.h"
23 #include "base/stack_container.h" 24 #include "base/stack_container.h"
24 #include "base/stats_table.h" 25 #include "base/stats_table.h"
25 #include "base/string_util.h" 26 #include "base/string_util.h"
26 #include "base/trace_event.h" 27 #include "base/trace_event.h"
27 #include "breakpad/src/client/windows/handler/exception_handler.h" 28 #include "breakpad/src/client/windows/handler/exception_handler.h"
28 #include "net/base/cookie_monster.h" 29 #include "net/base/cookie_monster.h"
29 #include "net/base/net_module.h" 30 #include "net/base/net_module.h"
30 #include "net/http/http_cache.h" 31 #include "net/http/http_cache.h"
31 #include "net/http/http_network_layer.h" 32 #include "net/http/http_network_layer.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 newPath->append(L".dmp"); 105 newPath->append(L".dmp");
105 106
106 // May use the heap, but oh well. If this fails, we'll just have the 107 // May use the heap, but oh well. If this fails, we'll just have the
107 // original dump file lying around. 108 // original dump file lying around.
108 _wrename(origPath->c_str(), newPath->c_str()); 109 _wrename(origPath->c_str(), newPath->c_str());
109 110
110 return false; 111 return false;
111 } 112 }
112 } // namespace 113 } // namespace
113 114
114 int main(int argc, char* argv[]) 115 int main(int argc, char* argv[]) {
115 { 116 process_util::EnableTerminationOnHeapCorruption();
116 #ifdef _CRTDBG_MAP_ALLOC 117 #ifdef _CRTDBG_MAP_ALLOC
117 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); 118 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
118 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); 119 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
119 #endif 120 #endif
120 // Some tests may use base::Singleton<>, thus we need to instanciate 121 // Some tests may use base::Singleton<>, thus we need to instanciate
121 // the AtExitManager or else we will leak objects. 122 // the AtExitManager or else we will leak objects.
122 base::AtExitManager at_exit_manager; 123 base::AtExitManager at_exit_manager;
123 124
124 CommandLine parsed_command_line; 125 CommandLine parsed_command_line;
125 if (parsed_command_line.HasSwitch(test_shell::kStartupDialog)) 126 if (parsed_command_line.HasSwitch(test_shell::kStartupDialog))
126 MessageBox(NULL, L"attach to me?", L"test_shell", MB_OK); 127 MessageBox(NULL, L"attach to me?", L"test_shell", MB_OK);
127 //webkit_glue::SetLayoutTestMode(true); 128 //webkit_glue::SetLayoutTestMode(true);
128 129
129 // Allocate a message loop for this thread. Although it is not used 130 // Allocate a message loop for this thread. Although it is not used
130 // directly, its constructor sets up some necessary state. 131 // directly, its constructor sets up some necessary state.
131 MessageLoopForUI main_message_loop; 132 MessageLoopForUI main_message_loop;
132 133
133 bool suppress_error_dialogs = 134 bool suppress_error_dialogs =
134 (GetEnvironmentVariable(L"CHROME_HEADLESS", NULL, 0) || 135 (GetEnvironmentVariable(L"CHROME_HEADLESS", NULL, 0) ||
135 parsed_command_line.HasSwitch(test_shell::kNoErrorDialogs) || 136 parsed_command_line.HasSwitch(test_shell::kNoErrorDialogs) ||
136 parsed_command_line.HasSwitch(test_shell::kLayoutTests)); 137 parsed_command_line.HasSwitch(test_shell::kLayoutTests));
137 TestShell::InitLogging(suppress_error_dialogs); 138 TestShell::InitLogging(suppress_error_dialogs);
138 139
139 // Suppress abort message in v8 library in debugging mode. 140 // Suppress abort message in v8 library in debugging mode.
140 // V8 calls abort() when it hits assertion errors. 141 // V8 calls abort() when it hits assertion errors.
141 if (suppress_error_dialogs) { 142 if (suppress_error_dialogs) {
142 _set_abort_behavior(0, _WRITE_ABORT_MSG); 143 _set_abort_behavior(0, _WRITE_ABORT_MSG);
143 } 144 }
144 145
145 if (parsed_command_line.HasSwitch(test_shell::kEnableTracing)) 146 if (parsed_command_line.HasSwitch(test_shell::kEnableTracing))
146 base::TraceLog::StartTracing(); 147 base::TraceLog::StartTracing();
147 148
148 // Make the selection of network stacks early on before any consumers try to 149 // Make the selection of network stacks early on before any consumers try to
149 // issue HTTP requests. 150 // issue HTTP requests.
150 if (parsed_command_line.HasSwitch(test_shell::kUseNewHttp)) 151 if (parsed_command_line.HasSwitch(test_shell::kUseNewHttp))
151 net::HttpNetworkLayer::UseWinHttp(false); 152 net::HttpNetworkLayer::UseWinHttp(false);
152 153
153 bool layout_test_mode = 154 bool layout_test_mode =
154 parsed_command_line.HasSwitch(test_shell::kLayoutTests); 155 parsed_command_line.HasSwitch(test_shell::kLayoutTests);
155 156
156 net::HttpCache::Mode cache_mode = net::HttpCache::NORMAL; 157 net::HttpCache::Mode cache_mode = net::HttpCache::NORMAL;
157 bool playback_mode = 158 bool playback_mode =
158 parsed_command_line.HasSwitch(test_shell::kPlaybackMode); 159 parsed_command_line.HasSwitch(test_shell::kPlaybackMode);
159 bool record_mode = 160 bool record_mode =
160 parsed_command_line.HasSwitch(test_shell::kRecordMode); 161 parsed_command_line.HasSwitch(test_shell::kRecordMode);
161 162
162 if (playback_mode) 163 if (playback_mode)
163 cache_mode = net::HttpCache::PLAYBACK; 164 cache_mode = net::HttpCache::PLAYBACK;
164 else if (record_mode) 165 else if (record_mode)
165 cache_mode = net::HttpCache::RECORD; 166 cache_mode = net::HttpCache::RECORD;
166 167
167 if (layout_test_mode || 168 if (layout_test_mode ||
168 parsed_command_line.HasSwitch(test_shell::kEnableFileCookies)) 169 parsed_command_line.HasSwitch(test_shell::kEnableFileCookies))
169 net::CookieMonster::EnableFileScheme(); 170 net::CookieMonster::EnableFileScheme();
170 171
171 std::wstring cache_path = 172 std::wstring cache_path =
172 parsed_command_line.GetSwitchValue(test_shell::kCacheDir); 173 parsed_command_line.GetSwitchValue(test_shell::kCacheDir);
173 if (cache_path.empty()) { 174 if (cache_path.empty()) {
174 PathService::Get(base::DIR_EXE, &cache_path); 175 PathService::Get(base::DIR_EXE, &cache_path);
175 file_util::AppendToPath(&cache_path, L"cache"); 176 file_util::AppendToPath(&cache_path, L"cache");
176 } 177 }
177 178
178 // Initializing with a default context, which means no on-disk cookie DB, 179 // Initializing with a default context, which means no on-disk cookie DB,
179 // and no support for directory listings. 180 // and no support for directory listings.
180 SimpleResourceLoaderBridge::Init( 181 SimpleResourceLoaderBridge::Init(
181 new TestShellRequestContext(cache_path, cache_mode)); 182 new TestShellRequestContext(cache_path, cache_mode));
182 183
183 // Load ICU data tables 184 // Load ICU data tables
184 icu_util::Initialize(); 185 icu_util::Initialize();
185 186
186 // Config the network module so it has access to a limited set of resources. 187 // Config the network module so it has access to a limited set of resources.
187 net::NetModule::SetResourceProvider(NetResourceProvider); 188 net::NetModule::SetResourceProvider(NetResourceProvider);
188 189
189 INITCOMMONCONTROLSEX InitCtrlEx; 190 INITCOMMONCONTROLSEX InitCtrlEx;
190 191
191 InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX); 192 InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
192 InitCtrlEx.dwICC = ICC_STANDARD_CLASSES; 193 InitCtrlEx.dwICC = ICC_STANDARD_CLASSES;
193 InitCommonControlsEx(&InitCtrlEx); 194 InitCommonControlsEx(&InitCtrlEx);
194 195
195 bool interactive = !layout_test_mode; 196 bool interactive = !layout_test_mode;
196 TestShell::InitializeTestShell(interactive); 197 TestShell::InitializeTestShell(interactive);
197 198
198 if (parsed_command_line.HasSwitch(test_shell::kAllowScriptsToCloseWindows)) 199 if (parsed_command_line.HasSwitch(test_shell::kAllowScriptsToCloseWindows))
199 TestShell::SetAllowScriptsToCloseWindows(); 200 TestShell::SetAllowScriptsToCloseWindows();
200 201
201 // Disable user themes for layout tests so pixel tests are consistent. 202 // Disable user themes for layout tests so pixel tests are consistent.
202 if (!interactive) 203 if (!interactive)
203 gfx::NativeTheme::instance()->DisableTheming(); 204 gfx::NativeTheme::instance()->DisableTheming();
204 205
205 if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) { 206 if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) {
206 const std::wstring timeout_str = parsed_command_line.GetSwitchValue( 207 const std::wstring timeout_str = parsed_command_line.GetSwitchValue(
207 test_shell::kTestShellTimeOut); 208 test_shell::kTestShellTimeOut);
208 int timeout_ms = static_cast<int>(StringToInt64(timeout_str.c_str())); 209 int timeout_ms = static_cast<int>(StringToInt64(timeout_str.c_str()));
209 if (timeout_ms > 0) 210 if (timeout_ms > 0)
210 TestShell::SetFileTestTimeout(timeout_ms); 211 TestShell::SetFileTestTimeout(timeout_ms);
211 } 212 }
212 213
213 // Initialize global strings 214 // Initialize global strings
214 TestShell::RegisterWindowClass(); 215 TestShell::RegisterWindowClass();
215 216
216 // Treat the first loose value as the initial URL to open. 217 // Treat the first loose value as the initial URL to open.
217 std::wstring uri; 218 std::wstring uri;
218 219
219 // Default to a homepage if we're interactive. 220 // Default to a homepage if we're interactive.
220 if (interactive) { 221 if (interactive) {
221 PathService::Get(base::DIR_SOURCE_ROOT, &uri); 222 PathService::Get(base::DIR_SOURCE_ROOT, &uri);
222 file_util::AppendToPath(&uri, L"webkit"); 223 file_util::AppendToPath(&uri, L"webkit");
223 file_util::AppendToPath(&uri, L"data"); 224 file_util::AppendToPath(&uri, L"data");
224 file_util::AppendToPath(&uri, L"test_shell"); 225 file_util::AppendToPath(&uri, L"test_shell");
225 file_util::AppendToPath(&uri, L"index.html"); 226 file_util::AppendToPath(&uri, L"index.html");
226 } 227 }
227 228
228 if (parsed_command_line.GetLooseValueCount() > 0) { 229 if (parsed_command_line.GetLooseValueCount() > 0) {
229 CommandLine::LooseValueIterator iter = parsed_command_line.GetLooseValue sBegin(); 230 CommandLine::LooseValueIterator iter(
230 uri = *iter; 231 parsed_command_line.GetLooseValuesBegin());
231 } 232 uri = *iter;
232 233 }
233 if (parsed_command_line.HasSwitch(test_shell::kCrashDumps)) { 234
234 std::wstring dir = parsed_command_line.GetSwitchValue(test_shell::kCrash Dumps); 235 if (parsed_command_line.HasSwitch(test_shell::kCrashDumps)) {
235 new google_breakpad::ExceptionHandler(dir, 0, &MinidumpCallback, 0, true ); 236 std::wstring dir(
236 } 237 parsed_command_line.GetSwitchValue(test_shell::kCrashDumps));
237 238 new google_breakpad::ExceptionHandler(dir, 0, &MinidumpCallback, 0, true);
238 std::wstring js_flags = 239 }
239 parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags); 240
240 // Test shell always exposes the GC. 241 std::wstring js_flags =
241 CommandLine::AppendSwitch(&js_flags, L"expose-gc"); 242 parsed_command_line.GetSwitchValue(test_shell::kJavaScriptFlags);
242 webkit_glue::SetJavaScriptFlags(js_flags); 243 // Test shell always exposes the GC.
243 244 CommandLine::AppendSwitch(&js_flags, L"expose-gc");
244 // load and initialize the stats table. 245 webkit_glue::SetJavaScriptFlags(js_flags);
245 StatsTable *table = new StatsTable(kStatsFile, kStatsFileThreads, kStatsFile Counters); 246
246 StatsTable::set_current(table); 247 // load and initialize the stats table.
247 248 StatsTable *table = new StatsTable(kStatsFile, kStatsFileThreads, kStatsFileCo unters);
248 TestShell* shell; 249 StatsTable::set_current(table);
249 if (TestShell::CreateNewWindow(uri, &shell)) { 250
250 if (record_mode || playback_mode) { 251 TestShell* shell;
251 // Move the window to the upper left corner for consistent 252 if (TestShell::CreateNewWindow(uri, &shell)) {
252 // record/playback mode. For automation, we want this to work 253 if (record_mode || playback_mode) {
253 // on build systems where the script invoking us is a background 254 // Move the window to the upper left corner for consistent
254 // process. So for this case, make our window the topmost window 255 // record/playback mode. For automation, we want this to work
255 // as well. 256 // on build systems where the script invoking us is a background
256 ForegroundHelper::SetForeground(shell->mainWnd()); 257 // process. So for this case, make our window the topmost window
257 ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0); 258 // as well.
258 // Tell webkit as well. 259 ForegroundHelper::SetForeground(shell->mainWnd());
259 webkit_glue::SetRecordPlaybackMode(true); 260 ::SetWindowPos(shell->mainWnd(), HWND_TOP, 0, 0, 600, 800, 0);
261 // Tell webkit as well.
262 webkit_glue::SetRecordPlaybackMode(true);
263 }
264
265 shell->Show(shell->webView(), NEW_WINDOW);
266
267 if (parsed_command_line.HasSwitch(test_shell::kDumpStatsTable))
268 shell->DumpStatsTableOnExit();
269
270 bool no_events = parsed_command_line.HasSwitch(test_shell::kNoEvents);
271 if ((record_mode || playback_mode) && !no_events) {
272 std::wstring script_path = cache_path;
273 // Create the cache directory in case it doesn't exist.
274 file_util::CreateDirectory(cache_path);
275 file_util::AppendToPath(&script_path, L"script.log");
276 if (record_mode)
277 base::EventRecorder::current()->StartRecording(script_path);
278 if (playback_mode)
279 base::EventRecorder::current()->StartPlayback(script_path);
280 }
281
282 if (parsed_command_line.HasSwitch(test_shell::kDebugMemoryInUse)) {
283 base::MemoryDebug::SetMemoryInUseEnabled(true);
284 // Dump all in use memory at startup
285 base::MemoryDebug::DumpAllMemoryInUse();
286 }
287
288 // See if we need to run the tests.
289 if (layout_test_mode) {
290 webkit_glue::SetLayoutTestMode(true);
291
292 // Set up for the kind of test requested.
293 TestShell::TestParams params;
294 if (parsed_command_line.HasSwitch(test_shell::kDumpPixels)) {
295 // The pixel test flag also gives the image file name to use.
296 params.dump_pixels = true;
297 params.pixel_file_name = parsed_command_line.GetSwitchValue(
298 test_shell::kDumpPixels);
299 if (params.pixel_file_name.size() == 0) {
300 fprintf(stderr, "No file specified for pixel tests");
301 exit(1);
260 } 302 }
261 303 }
262 shell->Show(shell->webView(), NEW_WINDOW); 304 if (parsed_command_line.HasSwitch(test_shell::kNoTree)) {
263 305 params.dump_tree = false;
264 if (parsed_command_line.HasSwitch(test_shell::kDumpStatsTable)) 306 }
265 shell->DumpStatsTableOnExit(); 307
266 308 if (uri.length() == 0) {
267 bool no_events = parsed_command_line.HasSwitch(test_shell::kNoEvents); 309 // Watch stdin for URLs.
268 if ((record_mode || playback_mode) && !no_events) { 310 char filenameBuffer[2048];
269 std::wstring script_path = cache_path; 311 while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
270 // Create the cache directory in case it doesn't exist. 312 char *newLine = strchr(filenameBuffer, '\n');
271 file_util::CreateDirectory(cache_path); 313 if (newLine)
272 file_util::AppendToPath(&script_path, L"script.log"); 314 *newLine = '\0';
273 if (record_mode) 315 if (!*filenameBuffer)
274 base::EventRecorder::current()->StartRecording(script_path); 316 continue;
275 if (playback_mode) 317
276 base::EventRecorder::current()->StartPlayback(script_path); 318 SetCurrentTestName(filenameBuffer);
319
320 if (!TestShell::RunFileTest(filenameBuffer, params))
321 break;
277 } 322 }
278 323 } else {
279 if (parsed_command_line.HasSwitch(test_shell::kDebugMemoryInUse)) { 324 TestShell::RunFileTest(WideToUTF8(uri).c_str(), params);
280 base::MemoryDebug::SetMemoryInUseEnabled(true); 325 }
281 // Dump all in use memory at startup 326
282 base::MemoryDebug::DumpAllMemoryInUse(); 327 shell->CallJSGC();
283 } 328 shell->CallJSGC();
284 329 if (shell) delete shell;
285 // See if we need to run the tests. 330 } else {
286 if (layout_test_mode) { 331 MessageLoop::current()->Run();
287 webkit_glue::SetLayoutTestMode(true); 332 }
288 333
289 // Set up for the kind of test requested. 334 // Flush any remaining messages. This ensures that any accumulated
290 TestShell::TestParams params; 335 // Task objects get destroyed before we exit, which avoids noise in
291 if (parsed_command_line.HasSwitch(test_shell::kDumpPixels)) { 336 // purify leak-test results.
292 // The pixel test flag also gives the image file name to use. 337 MessageLoop::current()->RunAllPending();
293 params.dump_pixels = true; 338
294 params.pixel_file_name = parsed_command_line.GetSwitchValue( 339 if (record_mode)
295 test_shell::kDumpPixels); 340 base::EventRecorder::current()->StopRecording();
296 if (params.pixel_file_name.size() == 0) { 341 if (playback_mode)
297 fprintf(stderr, "No file specified for pixel tests"); 342 base::EventRecorder::current()->StopPlayback();
298 exit(1); 343 }
299 } 344
300 } 345 TestShell::ShutdownTestShell();
301 if (parsed_command_line.HasSwitch(test_shell::kNoTree)) { 346 TestShell::CleanupLogging();
302 params.dump_tree = false; 347
303 } 348 // Tear down shared StatsTable; prevents unit_tests from leaking it.
304 349 StatsTable::set_current(NULL);
305 if (uri.length() == 0) { 350 delete table;
306 // Watch stdin for URLs.
307 char filenameBuffer[2048];
308 while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
309 char *newLine = strchr(filenameBuffer, '\n');
310 if (newLine)
311 *newLine = '\0';
312 if (!*filenameBuffer)
313 continue;
314
315 SetCurrentTestName(filenameBuffer);
316
317 if (!TestShell::RunFileTest(filenameBuffer, params))
318 break;
319 }
320 } else {
321 TestShell::RunFileTest(WideToUTF8(uri).c_str(), params);
322 }
323
324 shell->CallJSGC();
325 shell->CallJSGC();
326 if (shell) delete shell;
327 } else {
328 MessageLoop::current()->Run();
329 }
330
331 // Flush any remaining messages. This ensures that any accumulated
332 // Task objects get destroyed before we exit, which avoids noise in
333 // purify leak-test results.
334 MessageLoop::current()->RunAllPending();
335
336 if (record_mode)
337 base::EventRecorder::current()->StopRecording();
338 if (playback_mode)
339 base::EventRecorder::current()->StopPlayback();
340 }
341
342 TestShell::ShutdownTestShell();
343 TestShell::CleanupLogging();
344
345 // Tear down shared StatsTable; prevents unit_tests from leaking it.
346 StatsTable::set_current(NULL);
347 delete table;
348 351
349 #ifdef _CRTDBG_MAP_ALLOC 352 #ifdef _CRTDBG_MAP_ALLOC
350 _CrtDumpMemoryLeaks(); 353 _CrtDumpMemoryLeaks();
351 #endif 354 #endif
352 return 0; 355 return 0;
353 } 356 }
354
355
OLDNEW
« no previous file with comments | « webkit/tools/test_shell/run_all_tests.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698