OSDN Git Service

Perfprofd: Fix binder interface
[android-x86/system-extras.git] / simpleperf / record.h
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef SIMPLE_PERF_RECORD_H_
18 #define SIMPLE_PERF_RECORD_H_
19
20 #include <stdio.h>
21 #include <sys/types.h>
22
23 #include <memory>
24 #include <queue>
25 #include <string>
26 #include <vector>
27
28 #include <android-base/logging.h>
29
30 #include "build_id.h"
31 #include "CallChainJoiner.h"
32 #include "OfflineUnwinder.h"
33 #include "perf_event.h"
34
35 enum user_record_type {
36   PERF_RECORD_USER_DEFINED_TYPE_START = 64,
37   PERF_RECORD_ATTR = 64,
38   PERF_RECORD_EVENT_TYPE,
39   PERF_RECORD_TRACING_DATA,
40   PERF_RECORD_BUILD_ID,
41   PERF_RECORD_FINISHED_ROUND,
42
43   SIMPLE_PERF_RECORD_TYPE_START = 32768,
44   SIMPLE_PERF_RECORD_KERNEL_SYMBOL,
45   // TODO: remove DsoRecord and SymbolRecord.
46   SIMPLE_PERF_RECORD_DSO,
47   SIMPLE_PERF_RECORD_SYMBOL,
48   SIMPLE_PERF_RECORD_SPLIT,
49   SIMPLE_PERF_RECORD_SPLIT_END,
50   SIMPLE_PERF_RECORD_EVENT_ID,
51   SIMPLE_PERF_RECORD_CALLCHAIN,
52   SIMPLE_PERF_RECORD_UNWINDING_RESULT,
53 };
54
55 // perf_event_header uses u16 to store record size. However, that is not
56 // enough for storing records like KERNEL_SYMBOL or TRACING_DATA. So define
57 // a simpleperf_record_header struct to store record header for simpleperf
58 // defined records (type > SIMPLE_PERF_RECORD_TYPE_START).
59 struct simpleperf_record_header {
60   uint32_t type;
61   uint16_t size1;
62   uint16_t size0;
63 };
64
65 static_assert(
66     sizeof(simpleperf_record_header) == sizeof(perf_event_header),
67     "simpleperf_record_header should have the same size as perf_event_header");
68
69 struct PerfSampleIpType {
70   uint64_t ip;
71 };
72
73 struct PerfSampleTidType {
74   uint32_t pid, tid;
75 };
76
77 struct PerfSampleTimeType {
78   uint64_t time;
79 };
80
81 struct PerfSampleAddrType {
82   uint64_t addr;
83 };
84
85 struct PerfSampleIdType {
86   uint64_t id;
87 };
88
89 struct PerfSampleStreamIdType {
90   uint64_t stream_id;
91 };
92
93 struct PerfSampleCpuType {
94   uint32_t cpu, res;
95 };
96
97 struct PerfSamplePeriodType {
98   uint64_t period;
99 };
100
101 struct PerfSampleCallChainType {
102   uint64_t ip_nr;
103   uint64_t* ips;
104 };
105
106 struct PerfSampleRawType {
107   uint32_t size;
108   const char* data;
109 };
110
111 struct BranchStackItemType {
112   uint64_t from;
113   uint64_t to;
114   uint64_t flags;
115 };
116
117 struct PerfSampleBranchStackType {
118   uint64_t stack_nr;
119   const BranchStackItemType* stack;
120 };
121
122 struct PerfSampleRegsUserType {
123   uint64_t abi;
124   uint64_t reg_mask;
125   uint64_t reg_nr;
126   const uint64_t* regs;
127 };
128
129 struct PerfSampleStackUserType {
130   uint64_t size;
131   char* data;
132   uint64_t dyn_size;
133 };
134
135 struct RecordHeader {
136  public:
137   uint32_t type;
138   uint16_t misc;
139   uint32_t size;
140
141   RecordHeader() : type(0), misc(0), size(0) {}
142
143   explicit RecordHeader(const char* p) {
144     auto pheader = reinterpret_cast<const perf_event_header*>(p);
145     if (pheader->type < SIMPLE_PERF_RECORD_TYPE_START) {
146       type = pheader->type;
147       misc = pheader->misc;
148       size = pheader->size;
149     } else {
150       auto sheader = reinterpret_cast<const simpleperf_record_header*>(p);
151       type = sheader->type;
152       misc = 0;
153       size = (sheader->size1 << 16) | sheader->size0;
154     }
155   }
156
157   void MoveToBinaryFormat(char*& p) const {
158     if (type < SIMPLE_PERF_RECORD_TYPE_START) {
159       auto pheader = reinterpret_cast<perf_event_header*>(p);
160       pheader->type = type;
161       pheader->misc = misc;
162       CHECK_LT(size, 1u << 16);
163       pheader->size = static_cast<uint16_t>(size);
164     } else {
165       auto sheader = reinterpret_cast<simpleperf_record_header*>(p);
166       sheader->type = type;
167       CHECK_EQ(misc, 0u);
168       sheader->size1 = size >> 16;
169       sheader->size0 = size & 0xffff;
170     }
171     p += sizeof(perf_event_header);
172   }
173 };
174
175 // SampleId is optional at the end of a record in binary format. Its content is
176 // determined by sample_id_all and sample_type in perf_event_attr. To avoid the
177 // complexity of referring to perf_event_attr each time, we copy sample_id_all
178 // and sample_type inside the SampleId structure.
179 struct SampleId {
180   bool sample_id_all;
181   uint64_t sample_type;
182
183   PerfSampleTidType tid_data;    // Valid if sample_id_all && PERF_SAMPLE_TID.
184   PerfSampleTimeType time_data;  // Valid if sample_id_all && PERF_SAMPLE_TIME.
185   PerfSampleIdType id_data;      // Valid if sample_id_all && PERF_SAMPLE_ID.
186   PerfSampleStreamIdType
187       stream_id_data;  // Valid if sample_id_all && PERF_SAMPLE_STREAM_ID.
188   PerfSampleCpuType cpu_data;  // Valid if sample_id_all && PERF_SAMPLE_CPU.
189
190   SampleId();
191
192   // Create the content of sample_id. It depends on the attr we use.
193   size_t CreateContent(const perf_event_attr& attr, uint64_t event_id);
194
195   // Parse sample_id from binary format in the buffer pointed by p.
196   void ReadFromBinaryFormat(const perf_event_attr& attr, const char* p,
197                             const char* end);
198
199   // Write the binary format of sample_id to the buffer pointed by p.
200   void WriteToBinaryFormat(char*& p) const;
201   void Dump(size_t indent) const;
202   size_t Size() const;
203 };
204
205 // Usually one record contains the following three parts in order in binary
206 // format:
207 //   RecordHeader (at the head of a record, containing type and size info)
208 //   data depends on the record type
209 //   SampleId (optional part at the end of a record)
210 // We hold the common parts (RecordHeader and SampleId) in the base class
211 // Record, and hold the type specific data part in classes derived from Record.
212 struct Record {
213   RecordHeader header;
214   SampleId sample_id;
215
216   Record() : binary_(nullptr), own_binary_(false) {}
217   explicit Record(char* p) : header(p), binary_(p), own_binary_(false) {}
218   Record(Record&& other);
219
220   virtual ~Record() {
221     if (own_binary_) {
222       delete[] binary_;
223     }
224   }
225
226   void OwnBinary() { own_binary_ = true; }
227
228   uint32_t type() const { return header.type; }
229
230   uint16_t misc() const { return header.misc; }
231
232   uint32_t size() const { return header.size; }
233
234   static uint32_t header_size() { return sizeof(perf_event_header); }
235
236   bool InKernel() const {
237     return (header.misc & PERF_RECORD_MISC_CPUMODE_MASK) ==
238            PERF_RECORD_MISC_KERNEL;
239   }
240
241   void SetTypeAndMisc(uint32_t type, uint16_t misc) {
242     header.type = type;
243     header.misc = misc;
244   }
245
246   void SetSize(uint32_t size) { header.size = size; }
247
248   void Dump(size_t indent = 0) const;
249
250   const char* Binary() const { return binary_; }
251   char* BinaryForTestingOnly() { return binary_; }
252
253   virtual uint64_t Timestamp() const;
254   virtual uint32_t Cpu() const;
255   virtual uint64_t Id() const;
256
257  protected:
258   void UpdateBinary(char* new_binary);
259   virtual void DumpData(size_t) const = 0;
260
261   char* binary_;
262   bool own_binary_;
263
264   DISALLOW_COPY_AND_ASSIGN(Record);
265 };
266
267 struct MmapRecord : public Record {
268   struct MmapRecordDataType {
269     uint32_t pid, tid;
270     uint64_t addr;
271     uint64_t len;
272     uint64_t pgoff;
273   };
274   const MmapRecordDataType* data;
275   const char* filename;
276
277   MmapRecord(const perf_event_attr& attr, char* p);
278
279   MmapRecord(const perf_event_attr& attr, bool in_kernel, uint32_t pid,
280              uint32_t tid, uint64_t addr, uint64_t len, uint64_t pgoff,
281              const std::string& filename, uint64_t event_id, uint64_t time = 0);
282
283   void SetDataAndFilename(const MmapRecordDataType& data,
284                           const std::string& filename);
285
286  protected:
287   void DumpData(size_t indent) const override;
288 };
289
290 struct Mmap2Record : public Record {
291   struct Mmap2RecordDataType {
292     uint32_t pid, tid;
293     uint64_t addr;
294     uint64_t len;
295     uint64_t pgoff;
296     uint32_t maj;
297     uint32_t min;
298     uint64_t ino;
299     uint64_t ino_generation;
300     uint32_t prot, flags;
301   };
302   const Mmap2RecordDataType* data;
303   const char* filename;
304
305   Mmap2Record(const perf_event_attr& attr, char* p);
306
307   void SetDataAndFilename(const Mmap2RecordDataType& data,
308                           const std::string& filename);
309
310  protected:
311   void DumpData(size_t indent) const override;
312 };
313
314 struct CommRecord : public Record {
315   struct CommRecordDataType {
316     uint32_t pid, tid;
317   };
318   const CommRecordDataType* data;
319   const char* comm;
320
321   CommRecord(const perf_event_attr& attr, char* p);
322
323   CommRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid,
324              const std::string& comm, uint64_t event_id, uint64_t time);
325
326  protected:
327   void DumpData(size_t indent) const override;
328 };
329
330 struct ExitOrForkRecord : public Record {
331   struct ExitOrForkRecordDataType {
332     uint32_t pid, ppid;
333     uint32_t tid, ptid;
334     uint64_t time;
335   };
336   const ExitOrForkRecordDataType* data;
337
338   ExitOrForkRecord(const perf_event_attr& attr, char* p);
339
340   ExitOrForkRecord() : data(nullptr) {}
341
342  protected:
343   void DumpData(size_t indent) const override;
344 };
345
346 struct ExitRecord : public ExitOrForkRecord {
347   ExitRecord(const perf_event_attr& attr, char* p)
348       : ExitOrForkRecord(attr, p) {}
349 };
350
351 struct ForkRecord : public ExitOrForkRecord {
352   ForkRecord(const perf_event_attr& attr, char* p)
353       : ExitOrForkRecord(attr, p) {}
354
355   ForkRecord(const perf_event_attr& attr, uint32_t pid, uint32_t tid,
356              uint32_t ppid, uint32_t ptid, uint64_t event_id);
357 };
358
359 struct LostRecord : public Record {
360   uint64_t id;
361   uint64_t lost;
362
363   LostRecord(const perf_event_attr& attr, char* p);
364
365  protected:
366   void DumpData(size_t indent) const override;
367 };
368
369 struct SampleRecord : public Record {
370   uint64_t sample_type;  // sample_type is a bit mask determining which fields
371                          // below are valid.
372
373   PerfSampleIpType ip_data;               // Valid if PERF_SAMPLE_IP.
374   PerfSampleTidType tid_data;             // Valid if PERF_SAMPLE_TID.
375   PerfSampleTimeType time_data;           // Valid if PERF_SAMPLE_TIME.
376   PerfSampleAddrType addr_data;           // Valid if PERF_SAMPLE_ADDR.
377   PerfSampleIdType id_data;               // Valid if PERF_SAMPLE_ID.
378   PerfSampleStreamIdType stream_id_data;  // Valid if PERF_SAMPLE_STREAM_ID.
379   PerfSampleCpuType cpu_data;             // Valid if PERF_SAMPLE_CPU.
380   PerfSamplePeriodType period_data;       // Valid if PERF_SAMPLE_PERIOD.
381
382   PerfSampleCallChainType callchain_data;  // Valid if PERF_SAMPLE_CALLCHAIN.
383   PerfSampleRawType raw_data;              // Valid if PERF_SAMPLE_RAW.
384   PerfSampleBranchStackType
385       branch_stack_data;                  // Valid if PERF_SAMPLE_BRANCH_STACK.
386   PerfSampleRegsUserType regs_user_data;  // Valid if PERF_SAMPLE_REGS_USER.
387   PerfSampleStackUserType stack_user_data;  // Valid if PERF_SAMPLE_STACK_USER.
388
389   SampleRecord(const perf_event_attr& attr, char* p);
390   SampleRecord(const perf_event_attr& attr, uint64_t id, uint64_t ip,
391                uint32_t pid, uint32_t tid, uint64_t time, uint32_t cpu,
392                uint64_t period, const std::vector<uint64_t>& ips);
393
394   void ReplaceRegAndStackWithCallChain(const std::vector<uint64_t>& ips);
395   size_t ExcludeKernelCallChain();
396   bool HasUserCallChain() const;
397   void UpdateUserCallChain(const std::vector<uint64_t>& user_ips);
398   void RemoveInvalidStackData();
399
400   uint64_t Timestamp() const override;
401   uint32_t Cpu() const override;
402   uint64_t Id() const override;
403
404   uint64_t GetValidStackSize() const {
405     // If stack_user_data.dyn_size == 0, it may be because the kernel misses
406     // the patch to update dyn_size, like in N9 (See b/22612370). So assume
407     // all stack data is valid if dyn_size == 0.
408     if (stack_user_data.dyn_size == 0) {
409       return stack_user_data.size;
410     }
411     return stack_user_data.dyn_size;
412   }
413
414   void AdjustCallChainGeneratedByKernel();
415
416  protected:
417   void DumpData(size_t indent) const override;
418 };
419
420 // BuildIdRecord is defined in user-space, stored in BuildId feature section in
421 // record file.
422 struct BuildIdRecord : public Record {
423   uint32_t pid;
424   BuildId build_id;
425   const char* filename;
426
427   explicit BuildIdRecord(char* p);
428
429   BuildIdRecord(bool in_kernel, pid_t pid, const BuildId& build_id,
430                 const std::string& filename);
431
432  protected:
433   void DumpData(size_t indent) const override;
434 };
435
436 struct KernelSymbolRecord : public Record {
437   uint32_t kallsyms_size;
438   const char* kallsyms;
439
440   explicit KernelSymbolRecord(char* p);
441
442   explicit KernelSymbolRecord(const std::string& kallsyms);
443
444  protected:
445   void DumpData(size_t indent) const override;
446 };
447
448 struct DsoRecord : public Record {
449   uint64_t dso_type;
450   uint64_t dso_id;
451   uint64_t min_vaddr;
452   const char* dso_name;
453
454   explicit DsoRecord(char* p);
455
456   DsoRecord(uint64_t dso_type, uint64_t dso_id, const std::string& dso_name,
457             uint64_t min_vaddr);
458
459  protected:
460   void DumpData(size_t indent) const override;
461 };
462
463 struct SymbolRecord : public Record {
464   uint64_t addr;
465   uint64_t len;
466   uint64_t dso_id;
467   const char* name;
468
469   explicit SymbolRecord(char* p);
470
471   SymbolRecord(uint64_t addr, uint64_t len, const std::string& name,
472                uint64_t dso_id);
473
474  protected:
475   void DumpData(size_t indent) const override;
476 };
477
478 struct TracingDataRecord : public Record {
479   uint32_t data_size;
480   const char* data;
481
482   explicit TracingDataRecord(char* p);
483
484   explicit TracingDataRecord(const std::vector<char>& tracing_data);
485
486  protected:
487   void DumpData(size_t indent) const override;
488 };
489
490 struct EventIdRecord : public Record {
491   uint64_t count;
492   struct EventIdData {
493     uint64_t attr_id;
494     uint64_t event_id;
495   } const* data;
496
497   explicit EventIdRecord(char* p);
498
499   explicit EventIdRecord(const std::vector<uint64_t>& data);
500
501  protected:
502   void DumpData(size_t indent) const override;
503 };
504
505 struct CallChainRecord : public Record {
506   uint32_t pid;
507   uint32_t tid;
508   uint64_t chain_type;
509   uint64_t time;
510   uint64_t ip_nr;
511   uint64_t* ips;
512   uint64_t* sps;
513
514   explicit CallChainRecord(char* p);
515
516   CallChainRecord(pid_t pid, pid_t tid, simpleperf::CallChainJoiner::ChainType type, uint64_t time,
517                   const std::vector<uint64_t>& ips, const std::vector<uint64_t>& sps);
518
519   uint64_t Timestamp() const override {
520     return time;
521   }
522
523  protected:
524   void DumpData(size_t indent) const override;
525 };
526
527 struct UnwindingResultRecord : public Record {
528   uint64_t time;
529   simpleperf::UnwindingResult unwinding_result;
530
531   explicit UnwindingResultRecord(char* p);
532
533   UnwindingResultRecord(uint64_t time, const simpleperf::UnwindingResult& unwinding_result);
534
535   uint64_t Timestamp() const override {
536     return time;
537   }
538
539  protected:
540   void DumpData(size_t indent) const override;
541 };
542
543 // UnknownRecord is used for unknown record types, it makes sure all unknown
544 // records are not changed when modifying perf.data.
545 struct UnknownRecord : public Record {
546   const char* data;
547
548   explicit UnknownRecord(char* p);
549
550  protected:
551   void DumpData(size_t indent) const override;
552 };
553
554 // Read record from the buffer pointed by [p]. But the record doesn't own
555 // the buffer.
556 std::unique_ptr<Record> ReadRecordFromBuffer(const perf_event_attr& attr, uint32_t type, char* p);
557
558 // Read record from the buffer pointed by [p]. And the record owns the buffer.
559 std::unique_ptr<Record> ReadRecordFromOwnedBuffer(const perf_event_attr& attr,
560                                                   uint32_t type, char* p);
561
562 // Read records from the buffer pointed by [buf]. None of the records own
563 // the buffer.
564 std::vector<std::unique_ptr<Record>> ReadRecordsFromBuffer(
565     const perf_event_attr& attr, char* buf, size_t buf_size);
566
567 // Read one record from the buffer pointed by [p]. But the record doesn't
568 // own the buffer.
569 std::unique_ptr<Record> ReadRecordFromBuffer(const perf_event_attr& attr, char* p);
570
571 // RecordCache is a cache used when receiving records from the kernel.
572 // It sorts received records based on type and timestamp, and pops records
573 // in sorted order. Records from the kernel need to be sorted because
574 // records may come from different cpus at the same time, and it is affected
575 // by the order in which we collect records from different cpus.
576 // RecordCache pushes records and pops sorted record online. It uses two checks
577 // to help ensure that records are popped in order. Each time we pop a record A,
578 // it is the earliest record among all records in the cache. In addition, we
579 // have checks for min_cache_size and min_time_diff. For min_cache_size check,
580 // we check if the cache size >= min_cache_size, which is based on the
581 // assumption that if we have received (min_cache_size - 1) records after
582 // record A, we are not likely to receive a record earlier than A. For
583 // min_time_diff check, we check if record A is generated min_time_diff ns
584 // earlier than the latest record, which is based on the assumption that if we
585 // have received a record for time t, we are not likely to receive a record for
586 // time (t - min_time_diff) or earlier.
587 class RecordCache {
588  public:
589   explicit RecordCache(bool has_timestamp, size_t min_cache_size = 1000u,
590                        uint64_t min_time_diff_in_ns = 1000000u);
591   ~RecordCache();
592   void Push(std::unique_ptr<Record> record);
593   void Push(std::vector<std::unique_ptr<Record>> records);
594   std::unique_ptr<Record> Pop();
595   std::vector<std::unique_ptr<Record>> PopAll();
596   std::unique_ptr<Record> ForcedPop();
597
598  private:
599   struct RecordWithSeq {
600     uint32_t seq;
601     Record* record;
602
603     RecordWithSeq(uint32_t seq, Record* record) : seq(seq), record(record) {}
604     bool IsHappensBefore(const RecordWithSeq& other) const;
605   };
606
607   struct RecordComparator {
608     bool operator()(const RecordWithSeq& r1, const RecordWithSeq& r2);
609   };
610
611   bool has_timestamp_;
612   size_t min_cache_size_;
613   uint64_t min_time_diff_in_ns_;
614   uint64_t last_time_;
615   uint32_t cur_seq_;
616   std::priority_queue<RecordWithSeq, std::vector<RecordWithSeq>,
617                       RecordComparator> queue_;
618 };
619
620 #endif  // SIMPLE_PERF_RECORD_H_