@@ -176,25 +176,34 @@ statfunc bool vma_is_anon(struct vm_area_struct *vma)
176
176
// The golang heap consists of arenas which are memory regions mapped using mmap.
177
177
// When allocating areans, golang supplies mmap with an address hint, which is an
178
178
// address that the kernel should place the mapping at.
179
- // Hints are constant and vary between architectures, see `mallocinit()` in
180
- // https://github.com/golang/go/blob/master/src/runtime/malloc.go
179
+ // Hints for x86_64 begin at 0xc000000000 and for ARM64 at 0x4000000000.
181
180
// From observation, when allocating arenas the MAP_FIXED flag is used which forces
182
181
// the kernel to use the specified address or fail the mapping, so it is safe to
183
182
// rely on the address pattern to determine if it belongs to a heap arena.
184
- #define GOLANG_ARENA_HINT_MASK 0x80ff00000000UL
183
+ #define GOLANG_ARENA_HINT_MASK 0xffffffff00000000UL
185
184
#if defined(bpf_target_x86 )
186
185
#define GOLANG_ARENA_HINT (0xc0UL << 32)
187
186
#elif defined(bpf_target_arm64 )
188
187
#define GOLANG_ARENA_HINT (0x40UL << 32)
189
188
#else
190
189
#error Unsupported architecture
191
190
#endif
191
+ // We define a max hint that we assume golang allocations will never exceed.
192
+ // This translates to the address 0xff00000000.
193
+ // This means that we assume that a golang program will never allocate more than
194
+ // 256GB of memory on x86_64, or 768GB on ARM64.
195
+ #define GOLANG_ARENA_HINT_MAX (0xffUL << 32)
192
196
193
197
statfunc bool vma_is_golang_heap (struct vm_area_struct * vma )
194
198
{
195
199
u64 vm_start = BPF_CORE_READ (vma , vm_start );
196
200
197
- return (vm_start & GOLANG_ARENA_HINT_MASK ) == GOLANG_ARENA_HINT ;
201
+ // Check if the VMA address is in the range provided by golang heap arena address hints.
202
+ // Of course, any program can also allocate memory at these addresses which will result
203
+ // in a false positive for this check, so any caller of this function must make sure
204
+ // that a false positive for this check is acceptable.
205
+ return (vm_start & GOLANG_ARENA_HINT_MASK ) >= GOLANG_ARENA_HINT &&
206
+ (vm_start & GOLANG_ARENA_HINT_MASK ) <= GOLANG_ARENA_HINT_MAX ;
198
207
}
199
208
200
209
statfunc bool vma_is_thread_stack (task_info_t * task_info , struct vm_area_struct * vma )
0 commit comments