77#include "tsd.h"
88#include "types.h"
99
10- // get_m_ptr reads the M (machine/OS thread) pointer for the current goroutine.
11- // It does so by reading the G (goroutine) pointer from thread-local storage,
12- // then following the g.m pointer.
10+ // get_g_ptr reads the current G (goroutine) pointer from thread-local storage.
11+ // TLS always contains the G that is currently executing on the thread. During
12+ // systemstack/mcall, this is g0 (the system goroutine) since we are on the
13+ // system stack.
1314//
1415// On aarch64, when tls_offset is 0 (non-CGO binaries), the G pointer is taken
1516// from the r28 register saved in the unwind state instead of TLS.
16- static EBPF_INLINE void * get_m_ptr (struct GoLabelsOffsets * offs , UnwindState * state )
17+ static EBPF_INLINE u64 get_g_ptr (struct GoLabelsOffsets * offs , UnwindState * state )
1718{
1819#if defined(__x86_64__ )
1920 (void )state ;
2021#endif
2122 u64 g_addr = 0 ;
2223 void * tls_base = NULL ;
2324 if (tsd_get_base (& tls_base ) < 0 ) {
24- DEBUG_PRINT ("cl: failed to get tsd base; can't read m_ptr " );
25- return NULL ;
25+ DEBUG_PRINT ("cl: failed to get tsd base; can't read g_addr " );
26+ return 0 ;
2627 }
2728 DEBUG_PRINT (
2829 "cl: read tsd_base at 0x%lx, g offset: %d" , (unsigned long )tls_base , offs -> tls_offset );
@@ -33,17 +34,31 @@ static EBPF_INLINE void *get_m_ptr(struct GoLabelsOffsets *offs, UnwindState *st
3334 g_addr = state -> r28 ;
3435#elif defined(__x86_64__ )
3536 DEBUG_PRINT ("cl: TLS offset for g pointer missing for amd64" );
36- return NULL ;
37+ return 0 ;
3738#endif
3839 }
3940
4041 if (g_addr == 0 ) {
4142 if (bpf_probe_read_user (& g_addr , sizeof (void * ), (void * )((s64 )tls_base + offs -> tls_offset ))) {
4243 DEBUG_PRINT ("cl: failed to read g_addr, tls_base(%lx)" , (unsigned long )tls_base );
43- return NULL ;
44+ return 0 ;
4445 }
4546 }
4647
48+ DEBUG_PRINT ("cl: g_addr 0x%lx" , (unsigned long )g_addr );
49+ return g_addr ;
50+ }
51+
52+ // get_m_ptr reads the M (machine/OS thread) pointer for the current goroutine.
53+ // It does so by reading the G (goroutine) pointer from thread-local storage,
54+ // then following the g.m pointer.
55+ static EBPF_INLINE void * get_m_ptr (struct GoLabelsOffsets * offs , UnwindState * state )
56+ {
57+ u64 g_addr = get_g_ptr (offs , state );
58+ if (!g_addr ) {
59+ return NULL ;
60+ }
61+
4762 DEBUG_PRINT ("cl: reading m_ptr_addr at 0x%lx + 0x%x" , (unsigned long )g_addr , offs -> m_offset );
4863 void * m_ptr_addr ;
4964 if (bpf_probe_read_user (& m_ptr_addr , sizeof (void * ), (void * )(g_addr + offs -> m_offset ))) {
@@ -54,4 +69,4 @@ static EBPF_INLINE void *get_m_ptr(struct GoLabelsOffsets *offs, UnwindState *st
5469 return m_ptr_addr ;
5570}
5671
57- #endif // OPTI_GO_RUNTIME_H
72+ #endif // OPTI_GO_RUNTIME_H
0 commit comments