Hello Ian, Have you had the chance to look at this yet?
Let me know if there is a better way to do this. Greetings, Sören Sören Tempel <soe...@soeren-tempel.net> wrote: > Hi Ian, > > Thanks for your input! > > I am not familiar with Go runtime internals at all, but the patch below > at least compiles for me. Let me know if this works for you too / if > there is a better way to do this. The untyped uintptr_t seems to be > necessary as otherwise I encountered errors about &sevp escaping to the > heap. > > Sincerely, > Sören > > diff --git a/libgo/go/runtime/os_linux.go b/libgo/go/runtime/os_linux.go > index 96fb1788..6653d85e 100644 > --- a/libgo/go/runtime/os_linux.go > +++ b/libgo/go/runtime/os_linux.go > @@ -22,6 +22,8 @@ type mOS struct { > profileTimerValid uint32 > } > > +func setProcID(uintptr, int32) > + > func getProcID() uint64 { > return uint64(gettid()) > } > @@ -365,7 +367,7 @@ func setThreadCPUProfiler(hz int32) { > var sevp _sigevent > sevp.sigev_notify = _SIGEV_THREAD_ID > sevp.sigev_signo = _SIGPROF > - *((*int32)(unsafe.Pointer(&sevp._sigev_un))) = int32(mp.procid) > + setProcID(uintptr(unsafe.Pointer(&sevp)), int32(mp.procid)) > ret := timer_create(_CLOCK_THREAD_CPUTIME_ID, &sevp, &timerid) > if ret != 0 { > // If we cannot create a timer for this M, leave > profileTimerValid false > diff --git a/libgo/runtime/go-signal.c b/libgo/runtime/go-signal.c > index 528d9b6d..347b24e2 100644 > --- a/libgo/runtime/go-signal.c > +++ b/libgo/runtime/go-signal.c > @@ -183,6 +183,16 @@ setSigactionHandler(struct sigaction* sa, uintptr > handler) > sa->sa_sigaction = (void*)(handler); > } > > +void setProcID(uintptr_t, int32_t) > + __asm__ (GOSYM_PREFIX "runtime.setProcID"); > + > +void > +setProcID(uintptr_t ptr, int32_t v) > +{ > + struct sigevent *s = (void *)ptr; > + s->sigev_notify_thread_id = v; > +} > + > // C code to fetch values from the siginfo_t and ucontext_t pointers > // passed to a signal handler. > > Ian Lance Taylor <i...@golang.org> wrote: > > On Fri, Aug 12, 2022 at 10:21 AM Sören Tempel <soe...@soeren-tempel.net> > > wrote: > > > > > > This is one of the few remaining issues regarding musl compatibility for > > > gofrontend. Unfortunately, I am not sure how to best fix this one. Hence > > > reporting it here. > > > > > > The setThreadCPUProfiler implementation in libgo/go/runtime/os_linux.go > > > contains the following code: > > > > > > var sevp _sigevent > > > sevp.sigev_notify = _SIGEV_THREAD_ID > > > sevp.sigev_signo = _SIGPROF > > > *((*int32)(unsafe.Pointer(&sevp._sigev_un))) = int32(mp.procid) > > > > > > I am not entirely sure, but I assume the last line is supposed to access > > > the thread ID in struct sigevent. Unfortunately, it does so via the > > > glibc-specific _sigev_un member which doesn't work on musl libc (the > > > union is named __sev_fields on musl and hence causes a build failure). > > > > > > A portable way to access the thread ID in struct sigevent is via > > > sigev_notify_thread_id which is documented in timer_create(2). This is a > > > macro provided in siginfo.h from linux-headers for glibc [1] and in > > > signal.h for musl [2]. However, since it is macro it probably requires a > > > C wrapper function in order to be usable in libgo. Would be possible to > > > add that somehow to libgo or is there an alternative feasible solution > > > for this issue? > > > > I think you're right that a tiny C function is the way to go here. > > > > Ian