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 --- |