From 10f33b1bd6c6adb6306759a45bf3a5c18221d878 Mon Sep 17 00:00:00 2001 From: "brettw@chromium.org" Date: Sat, 1 Jan 2011 19:55:22 +0000 Subject: Move base/debug_on_start to base/debugger and rename it to be _win since it only does anything on Windows. TEST=it compiles BUG=none Review URL: http://codereview.chromium.org/5984007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@70362 0039d316-1c4b-4281-b951-d872f2087c98 --- base/base.gypi | 5 ++- base/base_switches.cc | 7 ++-- base/debug/debug_on_start_win.cc | 74 ++++++++++++++++++++++++++++++++++++++ base/debug/debug_on_start_win.h | 77 ++++++++++++++++++++++++++++++++++++++++ base/debug_on_start.cc | 68 ----------------------------------- base/debug_on_start.h | 68 ----------------------------------- base/test/test_suite.cc | 4 +-- 7 files changed, 159 insertions(+), 144 deletions(-) create mode 100644 base/debug/debug_on_start_win.cc create mode 100644 base/debug/debug_on_start_win.h delete mode 100644 base/debug_on_start.cc delete mode 100644 base/debug_on_start.h (limited to 'base') diff --git a/base/base.gypi b/base/base.gypi index ce533cb..53ca3c9 100644 --- a/base/base.gypi +++ b/base/base.gypi @@ -49,8 +49,8 @@ 'condition_variable_win.cc', 'cpu.cc', 'cpu.h', - 'debug_on_start.cc', - 'debug_on_start.h', + 'debug/debug_on_start_win.cc', + 'debug/debug_on_start_win.h', 'debug/debugger.cc', 'debug/debugger.h', 'debug/debugger_posix.cc', @@ -510,7 +510,6 @@ 'cpu.cc', 'crypto/capi_util.h', 'crypto/capi_util.cc', - 'debug_on_start.cc', 'event_recorder.cc', 'file_version_info.cc', 'pe_image.cc', diff --git a/base/base_switches.cc b/base/base_switches.cc index c95010e..a1d688a 100644 --- a/base/base_switches.cc +++ b/base/base_switches.cc @@ -6,9 +6,10 @@ namespace switches { -// If the program includes chrome/common/debug_on_start.h, the process will -// start the JIT system-registered debugger on itself and will wait for 60 -// seconds for the debugger to attach to itself. Then a break point will be hit. +// If the program includes base/debug/debug_on_start_win.h, the process will +// (on Windows only) start the JIT system-registered debugger on itself and +// will wait for 60 seconds for the debugger to attach to itself. Then a break +// point will be hit. const char kDebugOnStart[] = "debug-on-start"; // Disables the crash reporting. diff --git a/base/debug/debug_on_start_win.cc b/base/debug/debug_on_start_win.cc new file mode 100644 index 0000000..b5c1094 --- /dev/null +++ b/base/debug/debug_on_start_win.cc @@ -0,0 +1,74 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/debug/debug_on_start_win.h" + +#include + +#include "base/base_switches.h" +#include "base/basictypes.h" +#include "base/debug/debugger.h" + +namespace base { +namespace debug { + +// Minimalist implementation to try to find a command line argument. We can use +// kernel32 exported functions but not the CRT functions because we're too early +// in the process startup. +// The code is not that bright and will find things like ---argument or +// /-/argument. +// Note: command_line is non-destructively modified. +bool DebugOnStart::FindArgument(wchar_t* command_line, const char* argument_c) { + wchar_t argument[50]; + for (int i = 0; argument_c[i]; ++i) + argument[i] = argument_c[i]; + + int argument_len = lstrlen(argument); + int command_line_len = lstrlen(command_line); + while (command_line_len > argument_len) { + wchar_t first_char = command_line[0]; + wchar_t last_char = command_line[argument_len+1]; + // Try to find an argument. + if ((first_char == L'-' || first_char == L'/') && + (last_char == L' ' || last_char == 0 || last_char == L'=')) { + command_line[argument_len+1] = 0; + // Skip the - or / + if (lstrcmpi(command_line+1, argument) == 0) { + // Found it. + command_line[argument_len+1] = last_char; + return true; + } + // Fix back. + command_line[argument_len+1] = last_char; + } + // Continue searching. + ++command_line; + --command_line_len; + } + return false; +} + +// static +int __cdecl DebugOnStart::Init() { + // Try to find the argument. + if (FindArgument(GetCommandLine(), switches::kDebugOnStart)) { + // We can do 2 things here: + // - Ask for a debugger to attach to us. This involve reading the registry + // key and creating the process. + // - Do a int3. + + // It will fails if we run in a sandbox. That is expected. + base::debug::SpawnDebuggerOnProcess(GetCurrentProcessId()); + + // Wait for a debugger to come take us. + base::debug::WaitForDebugger(60, false); + } else if (FindArgument(GetCommandLine(), switches::kWaitForDebugger)) { + // Wait for a debugger to come take us. + base::debug::WaitForDebugger(60, true); + } + return 0; +} + +} // namespace debug +} // namespace base diff --git a/base/debug/debug_on_start_win.h b/base/debug/debug_on_start_win.h new file mode 100644 index 0000000..5a1081d --- /dev/null +++ b/base/debug/debug_on_start_win.h @@ -0,0 +1,77 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Define the necessary code and global data to look for kDebugOnStart command +// line argument. When the command line argument is detected, it invokes the +// debugger, if no system-wide debugger is registered, a debug break is done. + +#ifndef BASE_DEBUG_DEBUG_ON_START_WIN_H_ +#define BASE_DEBUG_DEBUG_ON_START_WIN_H_ +#pragma once + +#include "base/basictypes.h" +#include "build/build_config.h" + +// This only works on Windows. It's legal to include on other platforms, but +// will be a NOP. +#if defined(OS_WIN) + +#ifndef DECLSPEC_SELECTANY +#define DECLSPEC_SELECTANY __declspec(selectany) +#endif + +namespace base { +namespace debug { + +// Debug on start functions and data. +class DebugOnStart { + public: + // Expected function type in the .CRT$XI* section. + // Note: See VC\crt\src\internal.h for reference. + typedef int (__cdecl *PIFV)(void); + + // Looks at the command line for kDebugOnStart argument. If found, it invokes + // the debugger, if this fails, it crashes. + static int __cdecl Init(); + + // Returns true if the 'argument' is present in the 'command_line'. It does + // not use the CRT, only Kernel32 functions. + static bool FindArgument(wchar_t* command_line, const char* argument); +}; + +// Set the function pointer to our function to look for a crash on start. The +// XIB section is started pretty early in the program initialization so in +// theory it should be called before any user created global variable +// initialization code and CRT initialization code. +// Note: See VC\crt\src\defsects.inc and VC\crt\src\crt0.c for reference. +#ifdef _WIN64 + +// "Fix" the segment. On x64, the .CRT segment is merged into the .rdata segment +// so it contains const data only. +#pragma const_seg(push, ".CRT$XIB") +// Declare the pointer so the CRT will find it. +extern const DebugOnStart::PIFV debug_on_start; +DECLSPEC_SELECTANY const DebugOnStart::PIFV debug_on_start = + &DebugOnStart::Init; +// Fix back the segment. +#pragma const_seg(pop) + +#else // _WIN64 + +// "Fix" the segment. On x86, the .CRT segment is merged into the .data segment +// so it contains non-const data only. +#pragma data_seg(push, ".CRT$XIB") +// Declare the pointer so the CRT will find it. +DECLSPEC_SELECTANY DebugOnStart::PIFV debug_on_start = &DebugOnStart::Init; +// Fix back the segment. +#pragma data_seg(pop) + +#endif // _WIN64 + +} // namespace debug +} // namespace base + +#endif // defined(OS_WIN) + +#endif // BASE_DEBUG_DEBUG_ON_START_WIN_H_ diff --git a/base/debug_on_start.cc b/base/debug_on_start.cc deleted file mode 100644 index 15dab05..0000000 --- a/base/debug_on_start.cc +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include - -#include "base/debug_on_start.h" - -#include "base/base_switches.h" -#include "base/basictypes.h" -#include "base/debug/debugger.h" - -// Minimalist implementation to try to find a command line argument. We can use -// kernel32 exported functions but not the CRT functions because we're too early -// in the process startup. -// The code is not that bright and will find things like ---argument or -// /-/argument. -// Note: command_line is non-destructively modified. -bool DebugOnStart::FindArgument(wchar_t* command_line, const char* argument_c) { - wchar_t argument[50]; - for (int i = 0; argument_c[i]; ++i) - argument[i] = argument_c[i]; - - int argument_len = lstrlen(argument); - int command_line_len = lstrlen(command_line); - while (command_line_len > argument_len) { - wchar_t first_char = command_line[0]; - wchar_t last_char = command_line[argument_len+1]; - // Try to find an argument. - if ((first_char == L'-' || first_char == L'/') && - (last_char == L' ' || last_char == 0 || last_char == L'=')) { - command_line[argument_len+1] = 0; - // Skip the - or / - if (lstrcmpi(command_line+1, argument) == 0) { - // Found it. - command_line[argument_len+1] = last_char; - return true; - } - // Fix back. - command_line[argument_len+1] = last_char; - } - // Continue searching. - ++command_line; - --command_line_len; - } - return false; -} - -// static -int __cdecl DebugOnStart::Init() { - // Try to find the argument. - if (FindArgument(GetCommandLine(), switches::kDebugOnStart)) { - // We can do 2 things here: - // - Ask for a debugger to attach to us. This involve reading the registry - // key and creating the process. - // - Do a int3. - - // It will fails if we run in a sandbox. That is expected. - base::debug::SpawnDebuggerOnProcess(GetCurrentProcessId()); - - // Wait for a debugger to come take us. - base::debug::WaitForDebugger(60, false); - } else if (FindArgument(GetCommandLine(), switches::kWaitForDebugger)) { - // Wait for a debugger to come take us. - base::debug::WaitForDebugger(60, true); - } - return 0; -} diff --git a/base/debug_on_start.h b/base/debug_on_start.h deleted file mode 100644 index 1774415..0000000 --- a/base/debug_on_start.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Define the necessary code and global data to look for kDebugOnStart command -// line argument. When the command line argument is detected, it invokes the -// debugger, if no system-wide debugger is registered, a debug break is done. - -#ifndef BASE_DEBUG_ON_START_H_ -#define BASE_DEBUG_ON_START_H_ -#pragma once - -#include "base/basictypes.h" - -// This only works on Windows. -#if defined(OS_WIN) - -#ifndef DECLSPEC_SELECTANY -#define DECLSPEC_SELECTANY __declspec(selectany) -#endif - -// Debug on start functions and data. -class DebugOnStart { - public: - // Expected function type in the .CRT$XI* section. - // Note: See VC\crt\src\internal.h for reference. - typedef int (__cdecl *PIFV)(void); - - // Looks at the command line for kDebugOnStart argument. If found, it invokes - // the debugger, if this fails, it crashes. - static int __cdecl Init(); - - // Returns true if the 'argument' is present in the 'command_line'. It does - // not use the CRT, only Kernel32 functions. - static bool FindArgument(wchar_t* command_line, const char* argument); -}; - -// Set the function pointer to our function to look for a crash on start. The -// XIB section is started pretty early in the program initialization so in -// theory it should be called before any user created global variable -// initialization code and CRT initialization code. -// Note: See VC\crt\src\defsects.inc and VC\crt\src\crt0.c for reference. -#ifdef _WIN64 - -// "Fix" the segment. On x64, the .CRT segment is merged into the .rdata segment -// so it contains const data only. -#pragma const_seg(push, ".CRT$XIB") -// Declare the pointer so the CRT will find it. -extern const DebugOnStart::PIFV debug_on_start; -DECLSPEC_SELECTANY const DebugOnStart::PIFV debug_on_start = - &DebugOnStart::Init; -// Fix back the segment. -#pragma const_seg(pop) - -#else // _WIN64 - -// "Fix" the segment. On x86, the .CRT segment is merged into the .data segment -// so it contains non-const data only. -#pragma data_seg(push, ".CRT$XIB") -// Declare the pointer so the CRT will find it. -DECLSPEC_SELECTANY DebugOnStart::PIFV debug_on_start = &DebugOnStart::Init; -// Fix back the segment. -#pragma data_seg(pop) - -#endif // _WIN64 -#endif // defined(OS_WIN) - -#endif // BASE_DEBUG_ON_START_H_ diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index 2cfaa4b..aa23f04 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,7 +8,7 @@ #include "base/base_paths.h" #include "base/base_switches.h" #include "base/command_line.h" -#include "base/debug_on_start.h" +#include "base/debug/debug_on_start_win.h" #include "base/debug/debugger.h" #include "base/file_path.h" #include "base/i18n/icu_util.h" -- cgit v1.1