1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // This file declares the trace::agent_logger::AgentLogger class which
16 : // implements a simple logging service over RPC.
17 :
18 : #ifndef SYZYGY_TRACE_AGENT_LOGGER_AGENT_LOGGER_H_
19 : #define SYZYGY_TRACE_AGENT_LOGGER_AGENT_LOGGER_H_
20 :
21 : #include "base/callback.h"
22 : #include "base/files/file_util.h"
23 : #include "base/message_loop/message_loop.h"
24 : #include "base/process/process.h"
25 : #include "base/strings/string_piece.h"
26 : #include "base/threading/platform_thread.h"
27 : #include "syzygy/trace/common/service.h"
28 : #include "syzygy/trace/rpc/logger_rpc.h"
29 :
30 : namespace trace {
31 : namespace agent_logger {
32 :
33 : // Implements the Logger interface (see "logger_rpc.idl").
34 : //
35 : // Note: The Logger expects to be the only RPC service running in the process.
36 : class AgentLogger : public trace::common::Service {
37 : public:
38 : AgentLogger();
39 : virtual ~AgentLogger();
40 :
41 : // Set the destination file for this logger.
42 E : void set_destination(FILE* destination) {
43 E : DCHECK(destination != NULL);
44 E : base::AutoLock auto_lock(write_lock_);
45 E : destination_ = destination;
46 E : }
47 :
48 : // Get/Set the directory to which minidumps should be written.
49 : // @{
50 E : const base::FilePath& minidump_dir() const { return minidump_dir_; }
51 E : void set_minidump_dir(const base::FilePath& dir) { minidump_dir_ = dir; }
52 : // @}
53 :
54 : // Get/Set the symbolize_stack_traces_ flag.
55 : // @{
56 : bool symbolize_stack_traces() { return symbolize_stack_traces_; }
57 : void set_symbolize_stack_traces(bool value) {
58 : symbolize_stack_traces_ = value;
59 : }
60 : // @}
61 :
62 : // Append a trace dump for @p process, given @p trace_data containing
63 : // @p trace_length elements. The output will be appended to @p message.
64 : //
65 : // Note that the DWORD elements of @p trace_data are really void* values
66 : // pointing to the frame pointers of a call stack in @p process.
67 : //
68 : // Calls to this method are serialized under symbol_lock_.
69 : bool AppendTrace(HANDLE process,
70 : const DWORD* trace_data,
71 : size_t trace_length,
72 : std::string* message);
73 :
74 : // Captures a stack trace in a @p process given a program @p context.
75 : // @param process An open handle to the running process.
76 : // @param context The program context from which to trace.
77 : // @param trace_data The vector into which the trace will be populated.
78 : // @returns true on success, false otherwise.
79 : bool CaptureRemoteTrace(HANDLE process,
80 : CONTEXT* context,
81 : std::vector<DWORD>* trace_data);
82 :
83 : // Write @p message to the log destination. Note that calls to this method
84 : // are serialized using write_lock_.
85 : bool Write(const base::StringPiece& message);
86 :
87 : // Generate a minidump for the calling process.
88 : // @param process An open handle to the running process.
89 : // @param pid The process id of the process to dump.
90 : // @param tid The thread id (in the process to dump) of the thread which is
91 : // causing the minidump to be generated.
92 : // @param exc_ptr The pointer value (in the memory address space of the
93 : // process to dump) of the exception record for which the dump is being
94 : // generated.
95 : // @param protobuf The protobuf to include in the minidump.
96 : // @param protobuf_length The length of this protobuf.
97 : // @param memory_ranges_base_addresses An array containing the base addresses
98 : // of the memory ranges to include in this report.
99 : // @param memory_ranges_lengths An array containing the lengths of these
100 : // memory ranges.
101 : // @param memory_ranges_count The number of memory ranges to report.
102 : // @returns true on success, false otherwise.
103 : bool SaveMinidumpWithProtobufAndMemoryRanges(
104 : HANDLE process,
105 : base::ProcessId pid,
106 : DWORD tid,
107 : DWORD exc_ptr,
108 : const byte* protobuf,
109 : size_t protobuf_length,
110 : const void* const* memory_ranges_base_addresses,
111 : const size_t* memory_ranges_lengths,
112 : size_t memory_ranges_count);
113 :
114 : // Generate an event name used to signal that the logger is ready.
115 : // @param id The process id.
116 : // @param output The output string.
117 : static void GetSyzygyAgentLoggerEventName(const base::StringPiece16& id,
118 : std::wstring* output);
119 :
120 : protected:
121 : // @name Implementation of Service.
122 : // @{
123 : virtual bool StartImpl();
124 : virtual bool StopImpl();
125 : virtual bool JoinImpl();
126 : // @}
127 :
128 : // @name RPC Server Management Functions.
129 : // These functions, unless otherwise noted, are single threaded and must
130 : // all be called from the thread that created this instance.
131 : // @{
132 : bool InitRpc();
133 : bool StartRpc();
134 : bool StopRpc(); // This non-blocking function may be called from any thread.
135 : bool FinishRpc(); // This function is blocking.
136 : // @}
137 :
138 : // The file to which received log messages should be written. This must
139 : // remain valid for at least as long as the logger is valid. Writes to
140 : // the destination are serialized with lock_;
141 : FILE* destination_;
142 :
143 : // The directory to which minidumps should be written.
144 : base::FilePath minidump_dir_;
145 :
146 : // The lock used to serializes writes to destination_;
147 : base::Lock write_lock_;
148 :
149 : // The lock used to serialize access to the debug help library used to
150 : // symbolize traces.
151 : base::Lock symbol_lock_;
152 :
153 : // Indicates if we should symbolize the stack traces. Defaults to true.
154 : bool symbolize_stack_traces_;
155 :
156 : // Signaled once the agent has successfully initialized.
157 : base::win::ScopedHandle started_event_;
158 :
159 : private:
160 : DISALLOW_COPY_AND_ASSIGN(AgentLogger);
161 : };
162 :
163 : } // namespace agent_logger
164 : } // namespace trace
165 :
166 : #endif // SYZYGY_TRACE_AGENT_LOGGER_AGENT_LOGGER_H_
|