• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
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 
16 #ifndef PANDA_RUNTIME_TOOLING_SAMPLER_SAMPLE_WRITER_H
17 #define PANDA_RUNTIME_TOOLING_SAMPLER_SAMPLE_WRITER_H
18 
19 #include <iostream>
20 #include <string>
21 #include <fstream>
22 
23 #include "libpandabase/os/thread.h"
24 
25 #include "runtime/tooling/sampler/sample_info.h"
26 
27 #include <unordered_set>
28 
29 namespace ark::tooling::sampler {
30 
31 /*
32  * =======================================================
33  * =============  Sampler binary format ==================
34  * =======================================================
35  *
36  * Writing with the fasters and more convenient format .aspt
37  * Then it should be converted to flamegraph
38  *
39  * .aspt - ark sampling profiler trace file, binary format
40  *
41  * .aspt consists of 2 type information:
42  *   - module row (panda file and its pointer)
43  *   - sample row (sample information)
44  *
45  * module row for 64-bits:
46  *   first 8 byte is 0xFFFFFFFF (to recognize that it's not a sample row)
47  *   next 8 byte is pointer module
48  *   next 8 byte is size of panda file name
49  *   next bytes is panda file name in ASCII symbols
50  *
51  * sample row for 64-bits:
52  *   first 4 bytes is thread id of thread from sample was obtained
53  *   next 4 bytes is thread status of thread from sample was obtained
54  *   next 8 bytes is stack size
55  *   next bytes is stack frame
56  *   one stack frame is panda file ptr and file id
57  *
58  * Example for 64-bit architecture:
59  *
60  *            Thread id   Thread status    Stack Size      Managed stack frame id
61  * Sample row |___________|___________|________________|_____________------___________|
62  *              32 bits      32 bits        64 bits       (128 * <stack size>) bits
63  *
64  *              0xFF..FF    pointer   checksum   name size     module path (ASCII str)
65  * Module row |__________|__________|__________|___________|_____________------___________|
66  *              64 bits    64 bits    32 bits    64 bits       (8 * <name size>) bits
67  */
68 class StreamWriter final {
69 public:
StreamWriter(const char * filename)70     explicit StreamWriter(const char *filename)
71     {
72         /*
73          * This class instance should be used only from one thread
74          * It may lead to format invalidation
75          * This class wasn't made thread safe for performance reason
76          */
77         writeStreamPtr_ = std::make_unique<std::ofstream>(filename, std::ios::binary);
78         ASSERT(writeStreamPtr_ != nullptr);
79     }
80 
~StreamWriter()81     ~StreamWriter()
82     {
83         writeStreamPtr_->flush();
84         writeStreamPtr_->close();
85     };
86 
87     PANDA_PUBLIC_API void WriteModule(const FileInfo &moduleInfo);
88     PANDA_PUBLIC_API void WriteSample(const SampleInfo &sample) const;
89 
IsModuleWritten(const FileInfo & moduleInfo)90     bool IsModuleWritten(const FileInfo &moduleInfo) const
91     {
92         return writtenModules_.find(moduleInfo) != writtenModules_.end();
93     }
94 
95     NO_COPY_SEMANTIC(StreamWriter);
96     NO_MOVE_SEMANTIC(StreamWriter);
97 
98     static constexpr uintptr_t MODULE_INDICATOR_VALUE = 0xFFFFFFFF;
99 
100 private:
101     std::unique_ptr<std::ofstream> writeStreamPtr_;
102     std::unordered_set<FileInfo> writtenModules_;
103 };
104 
105 }  // namespace ark::tooling::sampler
106 
107 #endif  // PANDA_RUNTIME_TOOLING_SAMPLER_SAMPLE_WRITER_H
108