1 : // Copyright 2012 Google Inc.
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 : // Declares utility functions used by the call trace client and its unit
16 : // tests.
17 :
18 : #ifndef SYZYGY_TRACE_CLIENT_CLIENT_UTILS_H_
19 : #define SYZYGY_TRACE_CLIENT_CLIENT_UTILS_H_
20 :
21 : #include "syzygy/trace/protocol/call_trace_defs.h"
22 : #include "syzygy/trace/rpc/call_trace_rpc.h"
23 :
24 : namespace trace {
25 : namespace client {
26 :
27 : // This structure captures everything that a thread needs to know about
28 : // its current call trace buffer, which corresponds to a call trace segment
29 : // on disk. It holds the buffer information given by the call trace service,
30 : // the memory locations this buffer refers to in the client process, and a
31 : // pointer to the segment header within the buffer so that the segment can
32 : // be consistently maintained.
33 : class TraceFileSegment {
34 : public:
35 : TraceFileSegment();
36 :
37 : // @returns true if there's enough space left in the given segment to write
38 : // num_bytes of raw data.
39 : bool CanAllocateRaw(size_t num_bytes) const;
40 :
41 : // @returns true if there's enough space left in the given segment to write
42 : // a prefixed record of length num_bytes.
43 : bool CanAllocate(size_t num_bytes) const;
44 :
45 : // Writes the segment header at the top of a segment, updating the bytes
46 : // consumed and initializing the segment header structures.
47 : void WriteSegmentHeader(SessionHandle session_handle);
48 :
49 : // Allocate a variable length trace record. Typically this is used when
50 : // the record has a fixed set of fields followed by some variable size
51 : // blob or string. The size given must exceed the size of the records
52 : // fixed fields.
53 : //
54 : // @returns a pointer to the allocated record, such that you can populate
55 : // its values.
56 : template<typename RecordType>
57 E : inline RecordType* AllocateTraceRecord(size_t size) {
58 E : DCHECK(size >= sizeof(RecordType));
59 : return reinterpret_cast<RecordType*>(
60 E : AllocateTraceRecordImpl(RecordType::kTypeId, size));
61 E : }
62 :
63 : // Allocate a fixed length trace record.
64 : //
65 : // @returns a pointer to the allocated record, such that you can populate
66 : // its values.
67 : template<typename RecordType>
68 E : inline RecordType* AllocateTraceRecord() {
69 E : return AllocateTraceRecord<RecordType>(sizeof(RecordType));
70 E : }
71 :
72 : // TODO(siggi): Make this private.
73 : public:
74 : // Internal implementation of the trace record allocation function.
75 : void* AllocateTraceRecordImpl(int record_type,
76 : size_t record_size);
77 :
78 : // The structure used to communicate buffer information between the
79 : // client and call trace service.
80 : CallTraceBuffer buffer_info;
81 :
82 : // Points to the segment header within the call trace buffer. This
83 : // can be used to update the segment_length after appending new
84 : // data to the buffer.
85 : TraceFileSegmentHeader* header;
86 :
87 : // The lower bound of the call trace buffer in the client process.
88 : uint8* base_ptr;
89 :
90 : // The next memory location at which the client should write call
91 : // trace data.
92 : uint8* write_ptr;
93 :
94 : // The upper bound of the call trace buffer in the client process.
95 : uint8* end_ptr;
96 : };
97 :
98 : // Helper function to transform a DllMain reason to a call trace even type.
99 : int ReasonToEventType(DWORD reason);
100 :
101 : // Helper function to get pointer to the prefix for any record
102 : // in a trace file segment.
103 : RecordPrefix* GetRecordPrefix(void *record);
104 :
105 : } // namespace trace::client
106 : } // namespace trace
107 :
108 : #endif // SYZYGY_TRACE_CLIENT_CLIENT_UTILS_H_
|