Commit 102bbfba authored by jbates@chromium.org's avatar jbates@chromium.org

Make printf and LOG output to cmd console for Windows

BUG=142722


Review URL: https://chromiumcodereview.appspot.com/10832309

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152432 0039d316-1c4b-4281-b951-d872f2087c98
parent ab17025f
......@@ -138,6 +138,12 @@ enum TerminationStatus {
BASE_EXPORT extern size_t g_oom_size;
#endif
#if defined(OS_WIN)
// Output multi-process printf, cout, cerr, etc to the cmd.exe console that ran
// chrome. This is not thread-safe: only call from main thread.
BASE_EXPORT void RouteStdioToConsole();
#endif
// Returns the id of the current process.
BASE_EXPORT ProcessId GetCurrentProcId();
......@@ -832,7 +838,7 @@ BASE_EXPORT malloc_zone_t* GetPurgeableZone();
// Enables stack dump to console output on exception and signals.
// When enabled, the process will quit immediately. This is meant to be used in
// unit_tests only!
// unit_tests only! This is not thread-safe: only call from main thread.
BASE_EXPORT bool EnableInProcessStackDumping();
// If supported on the platform, and the user has sufficent rights, increase
......
......@@ -69,39 +69,6 @@ long WINAPI StackDumpExceptionFilter(EXCEPTION_POINTERS* info) {
return EXCEPTION_CONTINUE_SEARCH;
}
// Connects back to a console if available.
void AttachToConsole() {
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
unsigned int result = GetLastError();
// Was probably already attached.
if (result == ERROR_ACCESS_DENIED)
return;
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();
}
void OnNoMemory() {
// Kill the process. This is important for security, since WebKit doesn't
// NULL-check many memory allocations. If a malloc fails, returns NULL, and
......@@ -167,6 +134,38 @@ void TimerExpiredTask::KillProcess() {
} // namespace
void RouteStdioToConsole() {
if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
unsigned int result = GetLastError();
// Was probably already attached.
if (result == ERROR_ACCESS_DENIED)
return;
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();
}
ProcessId GetCurrentProcId() {
return ::GetCurrentProcessId();
}
......@@ -954,7 +953,7 @@ 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();
RouteStdioToConsole();
return true;
}
......
......@@ -530,6 +530,12 @@ static void ReleaseFreeMemoryThunk() {
SetContentClient(&empty_content_client_);
ContentClientInitializer::Set(process_type, delegate_);
#if defined(OS_WIN)
// Route stdio to parent console (if any) or create one.
if (command_line.HasSwitch(switches::kEnableLogging))
base::RouteStdioToConsole();
#endif
// Enable startup tracing asap to avoid early TRACE_EVENT calls being
// ignored.
if (command_line.HasSwitch(switches::kTraceStartup)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment