blob: 3e69a292eb17d6157409b30dc4b9333c8c585cd2 [file] [log] [blame]
Teng Qinef9d83f2019-02-28 15:29:55 -08001/*
2 * Copyright (c) Facebook, Inc.
3 * Licensed under the Apache License, Version 2.0 (the "License")
4 */
5
6#pragma once
7
8#include <string>
9#include <vector>
10
11#include <linux/perf_event.h>
12#include <sys/types.h>
13
14#include "BPF.h"
15#include "PyPerfType.h"
16
17namespace ebpf {
18namespace pyperf {
19
20class PyPerfUtil {
21 public:
22 enum class PyPerfResult : int {
23 SUCCESS = 0,
24 INIT_FAIL,
25 PERF_BUF_OPEN_FAIL,
26 NO_INIT,
27 EVENT_ATTACH_FAIL,
28 EVENT_DETACH_FAIL
29 };
30
31 struct Sample {
32 pid_t pid;
33 pid_t tid;
34 std::string comm;
35 uint8_t threadStateMatch;
36 uint8_t gilState;
37 uint8_t pthreadIDMatch;
38 uint8_t stackStatus;
39 std::vector<int32_t> pyStackIds;
40
41 explicit Sample(const Event* raw, int rawSize)
42 : pid(raw->pid),
43 tid(raw->tid),
44 comm(raw->comm),
45 threadStateMatch(raw->thread_state_match),
46 gilState(raw->gil_state),
47 pthreadIDMatch(raw->pthread_id_match),
48 stackStatus(raw->stack_status),
49 pyStackIds(raw->stack, raw->stack + raw->stack_len) {}
50 };
51
52 // init must be invoked exactly once before invoking profile
53 PyPerfResult init();
54
55 PyPerfResult profile(int64_t sampleRate, int64_t durationMs);
56
57 private:
58 uint32_t lostSymbols_ = 0, totalSamples_ = 0, lostSamples_ = 0, truncatedStack_ = 0;
59
60 ebpf::BPF bpf_{0, nullptr, false, "", true};
61 std::vector<Sample> samples_;
62 bool initCompleted_{false};
63
64 void handleSample(const void* data, int dataSize);
65 void handleLostSamples(int lostCnt);
66 friend void handleLostSamplesCallback(void*, uint64_t);
67 friend void handleSampleCallback(void*, void*, int);
68
69 std::string getSymbolName(Symbol& sym) const;
70
71 bool tryTargetPid(int pid, PidData& data);
72};
73} // namespace pyperf
74} // namespace ebpf