9
9
#include < yt/yt/core/misc/crash_handler.h>
10
10
#include < yt/yt/core/misc/error.h>
11
11
12
+ #include < yt/yt/core/ytree/yson_struct.h>
13
+
14
+ #include < yt/yt/core/yson/writer.h>
15
+
12
16
#include < library/cpp/yt/string/format.h>
13
17
14
18
#include < library/cpp/yt/memory/atomic_intrusive_ptr.h>
@@ -31,9 +35,9 @@ namespace NYT {
31
35
32
36
// //////////////////////////////////////////////////////////////////////////////
33
37
34
- void CollectAndDumpMemoryProfile (const TString& memoryProfilePath)
38
+ void CollectAndDumpMemoryProfile (const TString& memoryProfilePath, tcmalloc::ProfileType profileType )
35
39
{
36
- auto profile = NYTProf::ReadHeapProfile (tcmalloc::ProfileType:: kHeap );
40
+ auto profile = NYTProf::ReadHeapProfile (profileType );
37
41
SymbolizeByExternalPProf (&profile, NYTProf::TSymbolizationOptions{
38
42
.RunTool = [] (const std::vector<TString>& args) {
39
43
TShellCommand command{args[0 ], TList<TString>{args.begin ()+1 , args.end ()}};
@@ -62,6 +66,40 @@ void SetupMemoryProfileTimeout(int timeout)
62
66
63
67
// //////////////////////////////////////////////////////////////////////////////
64
68
69
+ DECLARE_REFCOUNTED_STRUCT (TOomProfilePaths)
70
+
71
+ struct TOomProfilePaths
72
+ : public NYTree::TYsonStruct
73
+ {
74
+ TString HeapProfilePath;
75
+ TString PeakProfilePath;
76
+
77
+ REGISTER_YSON_STRUCT (TOomProfilePaths);
78
+
79
+ static void Register (TRegistrar registrar)
80
+ {
81
+ registrar.Parameter (" heap_profile_path" , &TThis::HeapProfilePath)
82
+ .Default ();
83
+ registrar.Parameter (" peak_profile_path" , &TThis::PeakProfilePath)
84
+ .Default ();
85
+ }
86
+ };
87
+
88
+ DEFINE_REFCOUNTED_TYPE (TOomProfilePaths)
89
+
90
+ // //////////////////////////////////////////////////////////////////////////////
91
+
92
+ void DumpProfilePaths (const TOomProfilePathsPtr& links, const TString& fileName)
93
+ {
94
+ TFileOutput output (fileName);
95
+ NYson::TYsonWriter writer (&output, NYson::EYsonFormat::Pretty);
96
+ Serialize (links, &writer);
97
+ writer.Flush ();
98
+ output.Finish ();
99
+ }
100
+
101
+ // //////////////////////////////////////////////////////////////////////////////
102
+
65
103
class TTCMallocLimitHandler
66
104
: public TRefCounted
67
105
{
@@ -102,7 +140,6 @@ class TTCMallocLimitHandler
102
140
std::condition_variable CV_;
103
141
std::thread Thread_;
104
142
105
-
106
143
void Handle ()
107
144
{
108
145
std::unique_lock<std::mutex> lock (Mutex_);
@@ -114,19 +151,28 @@ class TTCMallocLimitHandler
114
151
return ;
115
152
}
116
153
117
- auto heapDumpPath = GetHeapDumpPath ();
154
+ auto timestamp = TInstant::Now ().FormatLocalTime (" %Y%m%dT%H%M%S" );
155
+ auto profilePaths = New<TOomProfilePaths>();
156
+ auto profilePathsFile = GetProfilePaths (timestamp);
157
+ profilePaths->HeapProfilePath = GetHeapDumpPath (timestamp);
158
+ profilePaths->PeakProfilePath = GetPeakDumpPath (timestamp);
159
+
118
160
Cerr << " TTCMallocLimitHandler: Fork process to write heap profile: "
119
- << heapDumpPath
161
+ << profilePaths->HeapProfilePath
162
+ << " peak profile path: " << profilePaths->PeakProfilePath
163
+ << " profiles path file: " << profilePathsFile
120
164
<< Endl;
121
165
122
166
SetupMemoryProfileTimeout (Options_.Timeout .Seconds ());
123
167
auto childPid = fork ();
124
168
125
169
if (childPid == 0 ) {
126
170
SetupMemoryProfileTimeout (Options_.Timeout .Seconds ());
127
- CollectAndDumpMemoryProfile (heapDumpPath);
171
+ CollectAndDumpMemoryProfile (profilePaths->HeapProfilePath , tcmalloc::ProfileType::kHeap );
172
+ CollectAndDumpMemoryProfile (profilePaths->PeakProfilePath , tcmalloc::ProfileType::kPeakHeap );
173
+ DumpProfilePaths (profilePaths, profilePathsFile);
128
174
129
- Cerr << " TTCMallocLimitHandler: Heap profile written" << Endl;
175
+ Cerr << " TTCMallocLimitHandler: Heap profiles are written" << Endl;
130
176
AbortProcess (ToUnderlying (EProcessExitCode::OK));
131
177
}
132
178
@@ -139,17 +185,33 @@ class TTCMallocLimitHandler
139
185
AbortProcess (ToUnderlying (EProcessExitCode::OK));
140
186
}
141
187
142
- TString GetHeapDumpPath () const
188
+ TString GetHeapDumpPath (const TString& timestamp ) const
143
189
{
144
190
return Format (
145
191
" %v/heap_%v.pb.gz" ,
146
192
Options_.HeapDumpDirectory ,
147
- TInstant::Now ().FormatLocalTime (" %Y%m%dT%H%M%S" ));
193
+ timestamp);
194
+ }
195
+
196
+ TString GetPeakDumpPath (const TString& timestamp) const
197
+ {
198
+ return Format (
199
+ " %v/peak_%v.pb.gz" ,
200
+ Options_.HeapDumpDirectory ,
201
+ timestamp);
202
+ }
203
+
204
+ TString GetProfilePaths (const TString& timestamp) const
205
+ {
206
+ return Format (
207
+ " %v/oom_profile_paths_%v.pb.gz" ,
208
+ Options_.HeapDumpDirectory ,
209
+ timestamp);
148
210
}
149
211
150
212
void ExecWaitForChild (int pid)
151
213
{
152
- Cerr << " TTCMallocLimitHandler: Before waiting for child" << Endl;
214
+ Cerr << " TTCMallocLimitHandler: Start waiting for the child" << Endl;
153
215
154
216
auto command = Format (" while [ -e /proc/%v ]; do sleep 1; done;" , pid);
155
217
execl (" /bin/bash" , " /bin/bash" , " -c" , command.c_str (), (void *)nullptr );
0 commit comments