1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Define the necessary code and global data to look for kDebugOnStart command
6// line argument. When the command line argument is detected, it invokes the
7// debugger, if no system-wide debugger is registered, a debug break is done.
8
9#ifndef BASE_DEBUG_DEBUG_ON_START_WIN_H_
10#define BASE_DEBUG_DEBUG_ON_START_WIN_H_
11#pragma once
12
13#include "base/basictypes.h"
14#include "build/build_config.h"
15
16// This only works on Windows. It's legal to include on other platforms, but
17// will be a NOP.
18#if defined(OS_WIN)
19
20#ifndef DECLSPEC_SELECTANY
21#define DECLSPEC_SELECTANY  __declspec(selectany)
22#endif
23
24namespace base {
25namespace debug {
26
27// There is no way for this code, as currently implemented, to work across DLLs.
28// TODO(rvargas): It looks like we really don't use this code, at least not for
29// Chrome. Figure out if it's really worth implementing something simpler.
30#if !defined(BASE_DLL)
31
32// Debug on start functions and data.
33class DebugOnStart {
34 public:
35  // Expected function type in the .CRT$XI* section.
36  // Note: See VC\crt\src\internal.h for reference.
37  typedef int  (__cdecl *PIFV)(void);
38
39  // Looks at the command line for kDebugOnStart argument. If found, it invokes
40  // the debugger, if this fails, it crashes.
41  static int __cdecl Init();
42
43  // Returns true if the 'argument' is present in the 'command_line'. It does
44  // not use the CRT, only Kernel32 functions.
45  static bool FindArgument(wchar_t* command_line, const char* argument);
46};
47
48// Set the function pointer to our function to look for a crash on start. The
49// XIB section is started pretty early in the program initialization so in
50// theory it should be called before any user created global variable
51// initialization code and CRT initialization code.
52// Note: See VC\crt\src\defsects.inc and VC\crt\src\crt0.c for reference.
53#ifdef _WIN64
54
55// "Fix" the segment. On x64, the .CRT segment is merged into the .rdata segment
56// so it contains const data only.
57#pragma const_seg(push, ".CRT$XIB")
58// Declare the pointer so the CRT will find it.
59extern const DebugOnStart::PIFV debug_on_start;
60DECLSPEC_SELECTANY const DebugOnStart::PIFV debug_on_start =
61    &DebugOnStart::Init;
62// Fix back the segment.
63#pragma const_seg(pop)
64
65#else  // _WIN64
66
67// "Fix" the segment. On x86, the .CRT segment is merged into the .data segment
68// so it contains non-const data only.
69#pragma data_seg(push, ".CRT$XIB")
70// Declare the pointer so the CRT will find it.
71DECLSPEC_SELECTANY DebugOnStart::PIFV debug_on_start = &DebugOnStart::Init;
72// Fix back the segment.
73#pragma data_seg(pop)
74
75#endif  // _WIN64
76
77#endif  // defined(BASE_DLL)
78
79}  // namespace debug
80}  // namespace base
81
82#endif  // defined(OS_WIN)
83
84#endif  // BASE_DEBUG_DEBUG_ON_START_WIN_H_
85