15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Need to include this before most other files because it defines 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC_MESSAGE_LOG_ENABLED. We need to use it to define 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC_MESSAGE_MACROS_LOG_ENABLED so render_messages.h will generate the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ViewMsgLog et al. functions. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On Windows, the about:ipc dialog shows IPCs; on POSIX, we hook up a 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// logger in this file. (We implement about:ipc on Mac but implement 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the loggers here anyway). We need to do this real early to be sure 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IPC_MESSAGE_MACROS_LOG_ENABLED doesn't get undefined. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) && defined(IPC_MESSAGE_LOG_ENABLED) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_MESSAGE_MACROS_LOG_ENABLED 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_ipc_logging.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \ 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RegisterIPCLogger(msg_id, logger) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/all_messages.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fstream> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/logging_chrome.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/debugger.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/dump_without_crashing.h" 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/env_vars.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_logging.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/chromeos_switches.h" 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <initguid.h> 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging_win.h" 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When true, this means that error dialogs should not be shown. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool dialogs_are_suppressed_ = false; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This should be true for exactly the period between the end of 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitChromeLogging() and the beginning of CleanupChromeLogging(). 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool chrome_logging_initialized_ = false; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Set if we called InitChromeLogging() but failed to initialize. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool chrome_logging_failed_ = false; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This should be true for exactly the period between the end of 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InitChromeLogging() and the beginning of CleanupChromeLogging(). 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool chrome_logging_redirected_ = false; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {7FE69228-633E-4f06-80C1-527FEA23E3A7} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GUID kChromeTraceProviderName = { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x7fe69228, 0x633e, 0x4f06, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } }; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Assertion handler for logging errors that occur when dialogs are 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// silenced. To record a new error, pass the log string associated 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with that error in the str parameter. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MSVC_DISABLE_OPTIMIZE(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SilentRuntimeAssertHandler(const std::string& str) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::debug::BreakDebugger(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SilentRuntimeReportHandler(const std::string& str) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handler to silently dump the current process when there is an assert in 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// chrome. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DumpProcessAssertHandler(const std::string& str) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) logging::DumpWithoutCrashing(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MSVC_ENABLE_OPTIMIZE(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Suppresses error/assertion dialogs and enables the logging of 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// those errors into silenced_errors_. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SuppressDialogs() { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dialogs_are_suppressed_) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetLogAssertHandler(SilentRuntimeAssertHandler); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetLogReportHandler(SilentRuntimeReportHandler); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT new_flags = SEM_FAILCRITICALERRORS | 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SEM_NOGPFAULTERRORBOX | 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SEM_NOOPENFILEERRORBOX; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Preserve existing error mode, as discussed at http://t/dmea 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT existing_flags = SetErrorMode(new_flags); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetErrorMode(existing_flags | new_flags); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dialogs_are_suppressed_ = true; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace logging { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoggingDestination DetermineLogMode(const CommandLine& command_line) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // only use OutputDebugString in debug mode 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_logging = false; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *kInvertLoggingSwitch = switches::kEnableLogging; 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const logging::LoggingDestination kDefaultLoggingMode = logging::LOG_TO_FILE; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool enable_logging = true; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *kInvertLoggingSwitch = switches::kDisableLogging; 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const logging::LoggingDestination kDefaultLoggingMode = logging::LOG_TO_ALL; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(kInvertLoggingSwitch)) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enable_logging = !enable_logging; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LoggingDestination log_mode; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enable_logging) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let --enable-logging=stderr force only stderr, particularly useful for 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // non-debug builds where otherwise you can't get logs to stderr at all. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.GetSwitchValueASCII(switches::kEnableLogging) == "stderr") 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_mode = logging::LOG_TO_SYSTEM_DEBUG_LOG; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_mode = kDefaultLoggingMode; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_mode = logging::LOG_NONE; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return log_mode; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath SetUpSymlinkIfNeeded(const base::FilePath& symlink_path, 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool new_log) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!symlink_path.empty()); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If not starting a new log, then just log through the existing 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // symlink, but if the symlink doesn't exist, create it. If 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // starting a new log, then delete the old symlink and make a new 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // one to a fresh log file. 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath target_path; 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool symlink_exists = base::PathExists(symlink_path); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (new_log || !symlink_exists) { 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path = GenerateTimestampedName(symlink_path, base::Time::Now()); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't care if the unlink fails; we're going to continue anyway. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::unlink(symlink_path.value().c_str()) == -1) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (symlink_exists) // only warn if we might expect it to succeed. 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(WARNING) << "Unable to unlink " << symlink_path.value(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_util::CreateSymbolicLink(target_path, symlink_path)) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Unable to create symlink " << symlink_path.value() 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " pointing at " << target_path.value(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!file_util::ReadSymbolicLink(symlink_path, &target_path)) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Unable to read symlink " << symlink_path.value(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return target_path; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void RemoveSymlinkAndLog(const base::FilePath& link_path, 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& target_path) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::unlink(link_path.value().c_str()) == -1) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(WARNING) << "Unable to unlink symlink " << link_path.value(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (::unlink(target_path.value().c_str()) == -1) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(WARNING) << "Unable to unlink log file " << target_path.value(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetSessionLogFile(const CommandLine& command_line) { 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath log_dir; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string log_dir_str; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env->GetVar(env_vars::kSessionLogDir, &log_dir_str) && 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !log_dir_str.empty()) { 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) log_dir = base::FilePath(log_dir_str); 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (command_line.HasSwitch(chromeos::switches::kLoginProfile)) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PathService::Get(chrome::DIR_USER_DATA, &log_dir); 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::FilePath profile_dir; 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (command_line.HasSwitch(switches::kMultiProfiles)) { 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // We could not use g_browser_process > profile_helper() here. 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string profile_dir_str = chrome::kProfileDirPrefix; 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile_dir_str.append( 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) command_line.GetSwitchValueASCII(chromeos::switches::kLoginProfile)); 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile_dir = base::FilePath(profile_dir_str); 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile_dir = 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) command_line.GetSwitchValuePath(chromeos::switches::kLoginProfile); 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) log_dir = log_dir.Append(profile_dir); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return log_dir.Append(GetLogFileName().BaseName()); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RedirectChromeLogging(const CommandLine& command_line) { 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kMultiProfiles) && 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome_logging_redirected_) { 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(nkostylev): Support multiple active users. http://crbug.com/230345 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "NOT redirecting logging for multi-profiles case."; 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!chrome_logging_redirected_) << 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Attempted to redirect logging when it was already initialized."; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Redirect logs to the session log directory, if set. Otherwise 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // defaults to the profile dir. 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath log_path = GetSessionLogFile(command_line); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creating symlink causes us to do blocking IO on UI thread. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Temporarily allow it until we fix http://crbug.com/61143 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowIO allow_io; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Always force a new symlink when redirecting. 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath target_path = SetUpSymlinkIfNeeded(log_path, true); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DcheckState dcheck_state = 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kEnableDCHECK) ? 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS : 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ChromeOS always logs through the symlink, so it shouldn't be 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deleted if it already exists. 253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch logging::LoggingSettings settings; 254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.logging_dest = DetermineLogMode(command_line); 255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.log_file = log_path.value().c_str(); 256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.dcheck_state = dcheck_state; 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!logging::InitLogging(settings)) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(ERROR) << "Unable to initialize logging to " << log_path.value(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveSymlinkAndLog(log_path, target_path); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_redirected_ = true; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_CHROMEOS 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitChromeLogging(const CommandLine& command_line, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OldFileDeletionState delete_old_log_file) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!chrome_logging_initialized_) << 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Attempted to initialize logging when it was already initialized."; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoggingDestination logging_dest = DetermineLogMode(command_line); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LogLockingState log_locking_state = LOCK_LOG_FILE; 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath log_path; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath target_path; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't resolve the log path unless we need to. Otherwise we leave an open 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ALPC handle after sandbox lockdown on Windows. 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((logging_dest & LOG_TO_FILE) != 0) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_path = GetLogFileName(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For BWSI (Incognito) logins, we want to put the logs in the user 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // profile directory that is created for the temporary session instead 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of in the system log directory, for privacy reasons. 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_line.HasSwitch(chromeos::switches::kGuestSession)) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_path = GetSessionLogFile(command_line); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On ChromeOS we log to the symlink. We force creation of a new 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // symlink if we've been asked to delete the old log, since that 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indicates the start of a new session. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_path = SetUpSymlinkIfNeeded( 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_path, delete_old_log_file == logging::DELETE_OLD_LOG_FILE); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Because ChromeOS manages the move to a new session by redirecting 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the link, it shouldn't remove the old file in the logging code, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since that will remove the newly created link instead. 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_old_log_file = logging::APPEND_TO_OLD_LOG_FILE; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_locking_state = DONT_LOCK_LOG_FILE; 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DcheckState dcheck_state = 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kEnableDCHECK) ? 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS : 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch logging::LoggingSettings settings; 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.logging_dest = logging_dest; 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.log_file = log_path.value().c_str(); 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.lock_log = log_locking_state; 315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.delete_old = delete_old_log_file; 316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.dcheck_state = dcheck_state; 317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool success = logging::InitLogging(settings); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Unable to initialize logging to " << log_path.value() 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " (which should be a link to " << target_path.value() << ")"; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RemoveSymlinkAndLog(log_path, target_path); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_failed_ = true; 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DPLOG(ERROR) << "Unable to initialize logging to " << log_path.value(); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_failed_ = true; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Default to showing error dialogs. 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoErrorDialogs)) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetShowErrorDialogs(true); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we want process and thread IDs because we have a lot of things running 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetLogItems(true, // enable_process_id 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // enable_thread_id 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, // enable_timestamp 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); // enable_tickcount 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We call running in unattended mode "headless", and allow 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // headless mode to be configured either by the Environment 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Variable or by the Command Line Switch. This is for 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // automated test purposes. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (env->HasVar(env_vars::kHeadless) || 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kNoErrorDialogs)) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SuppressDialogs(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use a minimum log level if the command line asks for one, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // otherwise leave it at the default level (INFO). 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kLoggingLevel)) { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string log_level = command_line.GetSwitchValueASCII( 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kLoggingLevel); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level = 0; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::StringToInt(log_level, &level) && 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level >= 0 && level < LOG_NUM_SEVERITIES) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetMinLogLevel(level); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "Bad log level: " << log_level; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enable trace control and transport through event tracing for Windows. 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LogEventProvider::Initialize(kChromeTraceProviderName); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line.HasSwitch(switches::kSilentDumpOnDCHECK) && 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) command_line.HasSwitch(switches::kEnableDCHECK)) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetLogReportHandler(DumpProcessAssertHandler); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NDEBUG 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_initialized_ = true; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a no-op, but we'll keep it around in case 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we need to do more cleanup in the future. 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CleanupChromeLogging() { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (chrome_logging_failed_) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // We failed to initiailize logging, no cleanup. 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(chrome_logging_initialized_) << 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Attempted to clean up logging when it wasn't initialized."; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseLogFile(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_initialized_ = false; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_logging_redirected_ = false; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetLogFileName() { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string filename; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::Environment> env(base::Environment::Create()); 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (env->GetVar(env_vars::kLogFileName, &filename) && !filename.empty()) 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return base::FilePath::FromUTF8Unsafe(filename); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath log_filename(FILE_PATH_LITERAL("chrome_debug.log")); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath log_path; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PathService::Get(chrome::DIR_LOGS, &log_path)) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_path = log_path.Append(log_filename); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return log_path; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // error with path service, just use some default file somewhere 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return log_filename; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DialogsAreSuppressed() { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dialogs_are_suppressed_; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetFatalAssertions(AssertionList* assertions) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In this function, we don't assume that assertions is non-null, so 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that if you just want an assertion count, you can pass in NULL. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (assertions) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertions->clear(); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t assertion_count = 0; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::ifstream log_file; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.open(GetLogFileName().value().c_str()); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!log_file.is_open()) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string utf8_line; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring wide_line; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!log_file.eof()) { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getline(log_file, utf8_line); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (utf8_line.find(":FATAL:") != std::string::npos) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wide_line = UTF8ToWide(utf8_line); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (assertions) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assertions->push_back(wide_line); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++assertion_count; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) log_file.close(); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return assertion_count; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GenerateTimestampedName(const base::FilePath& base_path, 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time timestamp) { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Exploded time_deets; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timestamp.LocalExplode(&time_deets); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string suffix = base::StringPrintf("_%02d%02d%02d-%02d%02d%02d", 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.year, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.month, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.day_of_month, 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.hour, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.minute, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time_deets.second); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_path.InsertBeforeExtensionASCII(suffix); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace logging 465