diff options
author | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-27 18:03:47 +0000 |
---|---|---|
committer | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-27 18:03:47 +0000 |
commit | d6fc9fd286eb7a3a6cad937da3b99cf8f4acd5c2 (patch) | |
tree | ff8de9ff438626c6d26a9df0acb94fadfd640431 /base/process_util_win.cc | |
parent | 30be1ce62471386dbdebf8d8f4f87e31a772661c (diff) | |
download | chromium_src-d6fc9fd286eb7a3a6cad937da3b99cf8f4acd5c2.zip chromium_src-d6fc9fd286eb7a3a6cad937da3b99cf8f4acd5c2.tar.gz chromium_src-d6fc9fd286eb7a3a6cad937da3b99cf8f4acd5c2.tar.bz2 |
Move console stack dumping code to a function so it can be reused in test_shell_tests.
TEST=none
BUG=13770
Review URL: http://codereview.chromium.org/339024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30220 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/process_util_win.cc')
-rw-r--r-- | base/process_util_win.cc | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/base/process_util_win.cc b/base/process_util_win.cc index eaa6c88..ea1df60 100644 --- a/base/process_util_win.cc +++ b/base/process_util_win.cc @@ -4,15 +4,22 @@ #include "base/process_util.h" +#include <fcntl.h> +#include <io.h> #include <windows.h> #include <winternl.h> #include <psapi.h> +#include <ios> + +#include "base/debug_util.h" #include "base/histogram.h" #include "base/logging.h" #include "base/scoped_handle_win.h" #include "base/scoped_ptr.h" +namespace base { + namespace { // System pagesize. This value remains constant on x86/64 architectures. @@ -21,9 +28,54 @@ const int PAGESIZE_KB = 4; // HeapSetInformation function pointer. typedef BOOL (WINAPI* HeapSetFn)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T); -} // namespace +// Previous unhandled filter. Will be called if not NULL when we intercept an +// exception. Only used in unit tests. +LPTOP_LEVEL_EXCEPTION_FILTER g_previous_filter = NULL; + +// Prints the exception call stack. +// This is the unit tests exception filter. +long WINAPI StackDumpExceptionFilter(EXCEPTION_POINTERS* info) { + StackTrace(info).PrintBacktrace(); + if (g_previous_filter) + return g_previous_filter(info); + return EXCEPTION_CONTINUE_SEARCH; +} + +// Connects back to a console if available. +// Only necessary on Windows, no-op on other platforms. +void AttachToConsole() { + if (!AttachConsole(ATTACH_PARENT_PROCESS)) { + unsigned int result = GetLastError(); + // Was probably already attached. + if (result == ERROR_ACCESS_DENIED) + return; -namespace base { + if (result == ERROR_INVALID_HANDLE || result == ERROR_INVALID_HANDLE) { + // TODO(maruel): Walk up the process chain if deemed necessary. + } + // Continue even if the function call fails. + AllocConsole(); + } + // http://support.microsoft.com/kb/105305 + int raw_out = _open_osfhandle( + reinterpret_cast<intptr_t>(GetStdHandle(STD_OUTPUT_HANDLE)), _O_TEXT); + *stdout = *_fdopen(raw_out, "w"); + setvbuf(stdout, NULL, _IONBF, 0); + + int raw_err = _open_osfhandle( + reinterpret_cast<intptr_t>(GetStdHandle(STD_ERROR_HANDLE)), _O_TEXT); + *stderr = *_fdopen(raw_err, "w"); + setvbuf(stderr, NULL, _IONBF, 0); + + int raw_in = _open_osfhandle( + reinterpret_cast<intptr_t>(GetStdHandle(STD_INPUT_HANDLE)), _O_TEXT); + *stdin = *_fdopen(raw_in, "r"); + setvbuf(stdin, NULL, _IONBF, 0); + // Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog. + std::ios::sync_with_stdio(); +} + +} // namespace ProcessId GetCurrentProcId() { return ::GetCurrentProcessId(); @@ -763,6 +815,14 @@ void EnableTerminationOnHeapCorruption() { HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); } +bool EnableInProcessStackDumping() { + // Add stack dumping support on exception on windows. Similar to OS_POSIX + // signal() handling in process_util_posix.cc. + g_previous_filter = SetUnhandledExceptionFilter(&StackDumpExceptionFilter); + AttachToConsole(); + return true; +} + void RaiseProcessToHighPriority() { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); } |