1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // =========================================================================== |
5 | // File: perfinfo.cpp |
6 | // |
7 | |
8 | #include "common.h" |
9 | |
10 | #if defined(FEATURE_PERFMAP) && !defined(DACCESS_COMPILE) |
11 | #include "perfinfo.h" |
12 | #include "pal.h" |
13 | |
14 | PerfInfo::PerfInfo(int pid) |
15 | : m_Stream(nullptr) |
16 | { |
17 | LIMITED_METHOD_CONTRACT; |
18 | |
19 | SString tempPath; |
20 | if (!WszGetTempPath(tempPath)) |
21 | { |
22 | return; |
23 | } |
24 | |
25 | SString path; |
26 | path.Printf("%Sperfinfo-%d.map" , tempPath.GetUnicode(), pid); |
27 | OpenFile(path); |
28 | } |
29 | |
30 | // Logs image loads into the process' perfinfo-%d.map file |
31 | void PerfInfo::LogImage(PEFile* pFile, WCHAR* guid) |
32 | { |
33 | CONTRACTL |
34 | { |
35 | THROWS; |
36 | GC_NOTRIGGER; |
37 | MODE_PREEMPTIVE; |
38 | PRECONDITION(pFile != nullptr); |
39 | PRECONDITION(guid != nullptr); |
40 | } CONTRACTL_END; |
41 | |
42 | SString value; |
43 | const SString& path = pFile->GetPath(); |
44 | value.Printf("%S%c%S" , path.GetUnicode(), sDelimiter, guid); |
45 | |
46 | SString command; |
47 | command.Printf("%s" , "ImageLoad" ); |
48 | WriteLine(command, value); |
49 | |
50 | } |
51 | |
52 | // Writes a command line, with "type" being the type of command, with "value" as the command's corresponding instructions/values. This is to be used to log specific information, e.g. LogImage |
53 | void PerfInfo::WriteLine(SString& type, SString& value) |
54 | { |
55 | |
56 | CONTRACTL |
57 | { |
58 | THROWS; |
59 | GC_NOTRIGGER; |
60 | MODE_PREEMPTIVE; |
61 | } CONTRACTL_END; |
62 | |
63 | if (m_Stream == nullptr) |
64 | { |
65 | return; |
66 | } |
67 | |
68 | SString line; |
69 | line.Printf("%S%c%S%c\n" , |
70 | type.GetUnicode(), sDelimiter, value.GetUnicode(), sDelimiter); |
71 | |
72 | EX_TRY |
73 | { |
74 | StackScratchBuffer scratch; |
75 | const char* strLine = line.GetANSI(scratch); |
76 | ULONG inCount = line.GetCount(); |
77 | ULONG outCount; |
78 | |
79 | m_Stream->Write(strLine, inCount, &outCount); |
80 | |
81 | if (inCount != outCount) |
82 | { |
83 | // error encountered |
84 | } |
85 | } |
86 | EX_CATCH{} EX_END_CATCH(SwallowAllExceptions); |
87 | } |
88 | |
89 | // Opens a file ready to be written in. |
90 | void PerfInfo::OpenFile(SString& path) |
91 | { |
92 | STANDARD_VM_CONTRACT; |
93 | |
94 | m_Stream = new (nothrow) CFileStream(); |
95 | |
96 | if (m_Stream != nullptr) |
97 | { |
98 | HRESULT hr = m_Stream->OpenForWrite(path.GetUnicode()); |
99 | if (FAILED(hr)) |
100 | { |
101 | delete m_Stream; |
102 | m_Stream = nullptr; |
103 | } |
104 | } |
105 | } |
106 | |
107 | PerfInfo::~PerfInfo() |
108 | { |
109 | LIMITED_METHOD_CONTRACT; |
110 | |
111 | delete m_Stream; |
112 | m_Stream = nullptr; |
113 | } |
114 | |
115 | |
116 | #endif |
117 | |
118 | |
119 | |
120 | |
121 | |
122 | |
123 | |
124 | |
125 | |
126 | |
127 | |