pyperf.h (0898782247ae533d1f4e47a06bc5d4870931b284) pyperf.h (50f9aa44cac7256551b2e0901831e432a6c52b7f)
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2019 Facebook
3#include <linux/sched.h>
4#include <linux/ptrace.h>
5#include <stdint.h>
6#include <stddef.h>
7#include <stdbool.h>
8#include <linux/bpf.h>

--- 58 unchanged lines hidden (view full) ---

67 void* co_name; // PyCodeObject.co_name
68} FrameData;
69
70static __always_inline void *get_thread_state(void *tls_base, PidData *pidData)
71{
72 void* thread_state;
73 int key;
74
1// SPDX-License-Identifier: GPL-2.0
2// Copyright (c) 2019 Facebook
3#include <linux/sched.h>
4#include <linux/ptrace.h>
5#include <stdint.h>
6#include <stddef.h>
7#include <stdbool.h>
8#include <linux/bpf.h>

--- 58 unchanged lines hidden (view full) ---

67 void* co_name; // PyCodeObject.co_name
68} FrameData;
69
70static __always_inline void *get_thread_state(void *tls_base, PidData *pidData)
71{
72 void* thread_state;
73 int key;
74
75 bpf_probe_read(&key, sizeof(key), (void*)(long)pidData->tls_key_addr);
76 bpf_probe_read(&thread_state, sizeof(thread_state),
77 tls_base + 0x310 + key * 0x10 + 0x08);
75 bpf_probe_read_user(&key, sizeof(key), (void*)(long)pidData->tls_key_addr);
76 bpf_probe_read_user(&thread_state, sizeof(thread_state),
77 tls_base + 0x310 + key * 0x10 + 0x08);
78 return thread_state;
79}
80
81static __always_inline bool get_frame_data(void *frame_ptr, PidData *pidData,
82 FrameData *frame, Symbol *symbol)
83{
84 // read data from PyFrameObject
78 return thread_state;
79}
80
81static __always_inline bool get_frame_data(void *frame_ptr, PidData *pidData,
82 FrameData *frame, Symbol *symbol)
83{
84 // read data from PyFrameObject
85 bpf_probe_read(&frame->f_back,
86 sizeof(frame->f_back),
87 frame_ptr + pidData->offsets.PyFrameObject_back);
88 bpf_probe_read(&frame->f_code,
89 sizeof(frame->f_code),
90 frame_ptr + pidData->offsets.PyFrameObject_code);
85 bpf_probe_read_user(&frame->f_back,
86 sizeof(frame->f_back),
87 frame_ptr + pidData->offsets.PyFrameObject_back);
88 bpf_probe_read_user(&frame->f_code,
89 sizeof(frame->f_code),
90 frame_ptr + pidData->offsets.PyFrameObject_code);
91
92 // read data from PyCodeObject
93 if (!frame->f_code)
94 return false;
91
92 // read data from PyCodeObject
93 if (!frame->f_code)
94 return false;
95 bpf_probe_read(&frame->co_filename,
96 sizeof(frame->co_filename),
97 frame->f_code + pidData->offsets.PyCodeObject_filename);
98 bpf_probe_read(&frame->co_name,
99 sizeof(frame->co_name),
100 frame->f_code + pidData->offsets.PyCodeObject_name);
95 bpf_probe_read_user(&frame->co_filename,
96 sizeof(frame->co_filename),
97 frame->f_code + pidData->offsets.PyCodeObject_filename);
98 bpf_probe_read_user(&frame->co_name,
99 sizeof(frame->co_name),
100 frame->f_code + pidData->offsets.PyCodeObject_name);
101 // read actual names into symbol
102 if (frame->co_filename)
101 // read actual names into symbol
102 if (frame->co_filename)
103 bpf_probe_read_str(&symbol->file,
104 sizeof(symbol->file),
105 frame->co_filename + pidData->offsets.String_data);
103 bpf_probe_read_user_str(&symbol->file,
104 sizeof(symbol->file),
105 frame->co_filename +
106 pidData->offsets.String_data);
106 if (frame->co_name)
107 if (frame->co_name)
107 bpf_probe_read_str(&symbol->name,
108 sizeof(symbol->name),
109 frame->co_name + pidData->offsets.String_data);
108 bpf_probe_read_user_str(&symbol->name,
109 sizeof(symbol->name),
110 frame->co_name +
111 pidData->offsets.String_data);
110 return true;
111}
112
113struct {
114 __uint(type, BPF_MAP_TYPE_HASH);
115 __uint(max_entries, 1);
116 __type(key, int);
117 __type(value, PidData);

--- 51 unchanged lines hidden (view full) ---

169
170 event->tid = (pid_t)pid_tgid;
171 bpf_get_current_comm(&event->comm, sizeof(event->comm));
172
173 event->user_stack_id = bpf_get_stackid(ctx, &stackmap, BPF_F_USER_STACK);
174 event->kernel_stack_id = bpf_get_stackid(ctx, &stackmap, 0);
175
176 void* thread_state_current = (void*)0;
112 return true;
113}
114
115struct {
116 __uint(type, BPF_MAP_TYPE_HASH);
117 __uint(max_entries, 1);
118 __type(key, int);
119 __type(value, PidData);

--- 51 unchanged lines hidden (view full) ---

171
172 event->tid = (pid_t)pid_tgid;
173 bpf_get_current_comm(&event->comm, sizeof(event->comm));
174
175 event->user_stack_id = bpf_get_stackid(ctx, &stackmap, BPF_F_USER_STACK);
176 event->kernel_stack_id = bpf_get_stackid(ctx, &stackmap, 0);
177
178 void* thread_state_current = (void*)0;
177 bpf_probe_read(&thread_state_current,
178 sizeof(thread_state_current),
179 (void*)(long)pidData->current_state_addr);
179 bpf_probe_read_user(&thread_state_current,
180 sizeof(thread_state_current),
181 (void*)(long)pidData->current_state_addr);
180
181 struct task_struct* task = (struct task_struct*)bpf_get_current_task();
182 void* tls_base = (void*)task;
183
184 void* thread_state = pidData->use_tls ? get_thread_state(tls_base, pidData)
185 : thread_state_current;
186 event->thread_current = thread_state == thread_state_current;
187
188 if (pidData->use_tls) {
189 uint64_t pthread_created;
190 uint64_t pthread_self;
182
183 struct task_struct* task = (struct task_struct*)bpf_get_current_task();
184 void* tls_base = (void*)task;
185
186 void* thread_state = pidData->use_tls ? get_thread_state(tls_base, pidData)
187 : thread_state_current;
188 event->thread_current = thread_state == thread_state_current;
189
190 if (pidData->use_tls) {
191 uint64_t pthread_created;
192 uint64_t pthread_self;
191 bpf_probe_read(&pthread_self, sizeof(pthread_self), tls_base + 0x10);
193 bpf_probe_read_user(&pthread_self, sizeof(pthread_self),
194 tls_base + 0x10);
192
195
193 bpf_probe_read(&pthread_created,
194 sizeof(pthread_created),
195 thread_state + pidData->offsets.PyThreadState_thread);
196 bpf_probe_read_user(&pthread_created,
197 sizeof(pthread_created),
198 thread_state +
199 pidData->offsets.PyThreadState_thread);
196 event->pthread_match = pthread_created == pthread_self;
197 } else {
198 event->pthread_match = 1;
199 }
200
201 if (event->pthread_match || !pidData->use_tls) {
202 void* frame_ptr;
203 FrameData frame;
204 Symbol sym = {};
205 int cur_cpu = bpf_get_smp_processor_id();
206
200 event->pthread_match = pthread_created == pthread_self;
201 } else {
202 event->pthread_match = 1;
203 }
204
205 if (event->pthread_match || !pidData->use_tls) {
206 void* frame_ptr;
207 FrameData frame;
208 Symbol sym = {};
209 int cur_cpu = bpf_get_smp_processor_id();
210
207 bpf_probe_read(&frame_ptr,
208 sizeof(frame_ptr),
209 thread_state + pidData->offsets.PyThreadState_frame);
211 bpf_probe_read_user(&frame_ptr,
212 sizeof(frame_ptr),
213 thread_state +
214 pidData->offsets.PyThreadState_frame);
210
211 int32_t* symbol_counter = bpf_map_lookup_elem(&symbolmap, &sym);
212 if (symbol_counter == NULL)
213 return 0;
214#ifdef NO_UNROLL
215#pragma clang loop unroll(disable)
216#else
217#pragma clang loop unroll(full)

--- 46 unchanged lines hidden ---
215
216 int32_t* symbol_counter = bpf_map_lookup_elem(&symbolmap, &sym);
217 if (symbol_counter == NULL)
218 return 0;
219#ifdef NO_UNROLL
220#pragma clang loop unroll(disable)
221#else
222#pragma clang loop unroll(full)

--- 46 unchanged lines hidden ---