Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/pprof: disasm not working on darwin #50891

Closed
rsc opened this issue Jan 28, 2022 · 40 comments
Closed

cmd/pprof: disasm not working on darwin #50891

rsc opened this issue Jan 28, 2022 · 40 comments
Labels
NeedsFix The path to resolution is known, but the work has not been done. OS-Darwin
Milestone

Comments

@rsc
Copy link
Contributor

rsc commented Jan 28, 2022

On my Mac, if I run go test -cpuprofile=x.prof anything, and then go tool pprof x.prof, then the disasm command in pprof does not work, for any function at all:

% go test -cpuprofile=x.prof strings
ok  	strings	1.059s
% go tool pprof x.prof
Type: cpu
Time: Jan 28, 2022 at 2:06pm (EST)
Duration: 805.01ms, Total samples = 540ms (67.08%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top10
Showing nodes accounting for 540ms, 100% of 540ms total
Showing top 10 nodes out of 27
      flat  flat%   sum%        cum   cum%
     210ms 38.89% 38.89%      210ms 38.89%  cmpbody
     170ms 31.48% 70.37%      170ms 31.48%  memeqbody
      50ms  9.26% 79.63%       50ms  9.26%  unicode.to
      50ms  9.26% 88.89%       50ms  9.26%  unicode/utf8.EncodeRune
      30ms  5.56% 94.44%      140ms 25.93%  strings.Map
      10ms  1.85% 96.30%       10ms  1.85%  runtime.decoderune
      10ms  1.85% 98.15%       10ms  1.85%  runtime.madvise
      10ms  1.85%   100%      390ms 72.22%  strings_test.TestCompareStrings
         0     0%   100%       10ms  1.85%  runtime.(*mcache).allocLarge
         0     0%   100%       10ms  1.85%  runtime.(*mheap).alloc
(pprof) disasm cmpbody
no matches found for regexp: cmpbody
(pprof) disasm unicode.to
no matches found for regexp: unicode.to
(pprof) disasm .*
no matches found for regexp: .*
(pprof) 

I have not checked whether this is Mac-specific.

@rsc rsc added NeedsFix The path to resolution is known, but the work has not been done. release-blocker labels Jan 28, 2022
@rsc rsc added this to the Go1.18 milestone Jan 28, 2022
@ALTree
Copy link
Member

ALTree commented Jan 28, 2022

go test -cpuprofile=x.prof strings will leave a strings.test binary in the working directory. If pprof is invoked as go tool pprof x.prof, disasm fails because it's looking for the binary in /tmp/, and it's not there:

(pprof) disasm cmpbody
open /tmp/go-build477592094/b001/strings.test: no such file or directory
no matches found for regexp: cmpbody

but if the binary (which is in wd) is explicitly passed as go tool pprof strings.test x.prof, then disasm works correctly.

FWIW, I see the same behaviour with go1.17.5 (above tests are from tip).

(This is on Linux).

@ianlancetaylor
Copy link
Contributor

Agreed, as far as I can tell this has never worked.

This works (on linux-amd64):

go test -c strings
./strings.test -test.cpuprofile=x.prof
go tool pprof x.prof
disasm cmpbody

Removing the release-blocker label.

@cespare
Copy link
Contributor

cespare commented Jan 28, 2022

I stub my toe on this UX about every other time I use pprof.

@cherrymui
Copy link
Member

It seems the go command first runs the binary in the tmp directory, collects the profile, then moves it to the current directory. The file path recorded is the one in the tmp directory.

$WORK/b001/strings.test -test.paniconexit0 -test.timeout=10m0s -test.outputdir=/tmp -test.cpuprofile=x.prof
mkdir -p /tmp/
mv $WORK/b001/strings.test /tmp/strings.test

Perhaps the go command can move the file first then run it?

Another part is that it seems the file names recorded in the profile are from profile.Mapping, which is from reading /proc/self/maps, which probably works only on Linux. So on macOS we may need to always pass the executable file name to pprof, even if the go command does the mv first.

@rsc
Copy link
Contributor Author

rsc commented Jan 31, 2022

Thanks. Indeed, not a release blocker. It should be easy to run the final executable instead of the one from /tmp to fix Linux. For the Mac we should be able to record os.Executable, which might be sufficient. All good things for a future release.

@fumin
Copy link

fumin commented Mar 29, 2022

Getting the same problem on Windows:

PS C:\Users\a3367\work\misc\seg> go run .\cmd\vizccl\main.go
2022/03/29 13:28:17.416938 C:/Users/a3367/work/misc/seg/cmd/vizccl/main.go:45: png write start output\vizqqq.png
2022/03/29 13:28:48.685875 C:/Users/a3367/work/misc/seg/cmd/vizccl/main.go:55: png write end output\vizqqq.png
PS C:\Users\a3367\work\misc\seg>
PS C:\Users\a3367\work\misc\seg\output> go tool pprof .\png_encode.pprof
Type: cpu
Time: Mar 29, 2022 at 1:28pm (CST)
Duration: 31.43s, Total samples = 17.53s (55.77%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof) top
Showing nodes accounting for 16.92s, 96.52% of 17.53s total
Dropped 91 nodes (cum <= 0.09s)
Showing top 10 nodes out of 29
      flat  flat%   sum%        cum   cum%
     7.96s 45.41% 45.41%     13.07s 74.56%  image/png.filter
        2s 11.41% 56.82%      2.01s 11.47%  image/png.abs
     1.74s  9.93% 66.74%      1.74s  9.93%  runtime.memmove
     1.56s  8.90% 75.64%      1.56s  8.90%  image/png.abs8
     1.44s  8.21% 83.86%      3.46s 19.74%  image/png.paeth
     0.90s  5.13% 88.99%      0.90s  5.13%  hash/adler32.update
     0.80s  4.56% 93.55%      0.81s  4.62%  compress/flate.(*deflateFast).matchLen
     0.29s  1.65% 95.21%      0.31s  1.77%  compress/flate.(*huffmanEncoder).bitCounts
     0.12s  0.68% 95.89%      0.12s  0.68%  runtime.asyncPreempt
     0.11s  0.63% 96.52%      1.04s  5.93%  compress/flate.(*deflateFast).encode
(pprof) disasm png.abs8
Total: 17.53s
(pprof)
$ go version
go version go1.17.6 windows/amd64
go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\a3367\AppData\Local\go-build
set GOENV=C:\Users\a3367\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\a3367\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\a3367\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.17.6
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\a3367\AppData\Local\Temp\go-build2334633044=/tmp/go-build -gno-record-gcc-switches
gdb --version: GNU gdb (GDB) 8.1

@fangsm26
Copy link

The interesting thing is that if you cross-compile an amd64 version of go on an m1 mac, and then use this go to test and profile, you can successfully execute disasm in pprof.

@erifan
Copy link

erifan commented Sep 19, 2022

Any update on this issue ? Given that gdb and perf tool are not available on m1 mac, pprof has become my first choice for debugging on m1 mac, and the ineffectiveness of disasm has caused great inconvenience.

@AlexanderYastrebov
Copy link
Contributor

but if the binary (which is in wd) is explicitly passed as go tool pprof strings.test x.prof, then disasm works correctly.

It also works after second run of go test -cpuprofile=x.prof strings because build uses existing strings.test binary and new x.prof contains path to it.

@cosnicolaou
Copy link
Contributor

I've done a bit of digging into this since I distinctly recall this working circa 2016-17. In short, this did work before a change to pprof that broke things initially for intel (2018 onward) and then for arm when it was introduced in 2020. Fixing pprof is easy and this fixes intel, but not arm macs. For arm, the pc values available within a running process differ from those in the executable's symbol table; this only happens for apple silicon systems and not for other arm (linux/raspberry pi) systems. The symbol table values are "correct" in the sense that objdump displays correct looking assembly code at those locations but are modified, I presume by dyld, when the executable is loaded into memory. In addition, the values change every time the process is run, suggesting that dyld is non-deterministic, which if correct, kinda sucks.

For pprof, google/pprof#313 introduced a check for 'textSegment.Addr > start' which will always fail since the text segments start at 0x100000000. The error occurs when testing for the first argument to pprof being an executable at startup (but the error is ignored there) and when attempting to load the executable when disassembly is requested. Again, no error is displayed. Fixing this fixes the problem for intel based macs, but not for arm based ones and explains why I recall this working correctly before 2018 or so. I am puzzled as to how some of the earlier notes on this thread state that the problem was the executable being in an inaccessible location.

For the eg.go shown below, here's the output on an arm mac and an intel one:

apple silicon - the values change every time it is run.

❯ go build -o eg eg.go
❯ ./eg
[100aa20e0 100aa20c9 100a49030 100a730e4]
100aa20df runtime.Callers
100aa20c8 main.main
100a4902f runtime.main
❯ nm eg | grep main.main
000000010008a090 t _main.main

intel:

❯ go build -o eg eg.go
❯  ~ ./eg
[108ac55 108ac43 10317d2 105a521]
108ac54 runtime.Callers
108ac42 main.main
10317d1 runtime.main
❯  ~ nm eg | grep main.main
000000000108ac00 t _main.main

arm64 on a linux raspberry pi:

 ./eg
[8ea50 8ea39 41bb0 6b474]
8ea4f runtime.Callers
8ea38 main.main
41baf runtime.main
cnicolaou@pa-dnsmasq-2:~$ nm eg | grep main.main
000000000008ea00 T main.main
package main

import (
	"fmt"
	"runtime"
)

func main() {
	pcs := make([]uintptr, 100)
	n := runtime.Callers(0, pcs)
	pcs = pcs[:n]
	fmt.Printf("%x\n", pcs)
	frames := runtime.CallersFrames(pcs[:n])
	for {
		frame, more := frames.Next()
		if !more {
			break
		}
		fmt.Printf("%x %s\n", frame.PC, frame.Function)
	}
}

@cosnicolaou
Copy link
Contributor

oh, it seems that src/runtime/pprof/proto_other.go's implementation of readMapping works only on linux - i.e. it reads /proc/self/maps which doesn't exist on macos. Maybe that should be using vmmap, or the underlying APIs that it uses?

@cosnicolaou
Copy link
Contributor

And sure enough, a quick hack (that runs vmmap) shows that this, at least for one test case, works. Ideally readMappings should use mach_vm_region rather than vmmap. With this in place, another issue with pprof shows up whereby listing source code via the webui (not the cli list command) breaks. This has not worked for so long now that other bugs have crept in.

@cosnicolaou
Copy link
Contributor

See https://go-review.googlesource.com/c/go/+/498375 for a proposed fix.

@cherrymui
Copy link
Member

@cosnicolaou thanks for the CL! As you noted, it is better to use the mach_vm_region API if possible. I was actually looking into this a while ago, made some progress but hasn't finished. Would you like to give that a try? Otherwise I can resume and try that. Thanks.

@cosnicolaou
Copy link
Contributor

If you give me some pointers as to how you'd like the new system call added to the runtime I can give it a try. I'm reasonably confident it will work since I already wrote a stand-alone C program to get the appropriate information, assuming you're ok with the assumption that the text section we care about is the first/lowest address? I didn't prototype any means of getting the name of the binary associated with a segment.

@cherrymui
Copy link
Member

https://cs.opensource.google/go/go/+/master:src/runtime/sys_darwin.go this contains the syscall code. Basically, it needs a Go function like https://cs.opensource.google/go/go/+/master:src/runtime/sys_darwin.go;l=123 , an import pragma like https://cs.opensource.google/go/go/+/master:src/runtime/sys_darwin.go;l=123 , and an assembly trampoline like https://cs.opensource.google/go/go/+/master:src/runtime/sys_darwin_amd64.s;l=415.

These are defined in the runtime package. You'll need to export them to the runtime/pprof package. You could do something similar to what we did for crypto/x509: https://cs.opensource.google/go/go/+/master:src/runtime/sys_darwin.go;l=105 and https://cs.opensource.google/go/go/+/master:src/crypto/x509/internal/macos/corefoundation.go;l=62

Yeah, I tried a C program, too, but didn't get a chance to port it to the Go runtime :)

assuming you're ok with the assumption that the text section we care about is the first/lowest address?

Yes, I think that should be fine. In fact I'm not sure we actually need this assumption. I think you can look for just the executable mappings, matching with the executable segments from the binary. For disassembly we only need executable segments anyway.

@cosnicolaou
Copy link
Contributor

I've spent a little time looking at this, and of course, have some questions!

  1. I need access to the various C types required by mach_vm_info. I see defs_darwin.go as being the place to access these, but the comments therein about using cgo -cdefs are out of date since cdefs no longer exists so far as I can tell. Is the current practice to run cgo --godefs and then to manually edit the defs_darwin_.go files? I found https://go-review.googlesource.com/c/go/+/496081 but I can't tell how the edits to the _.go files were achieved - I find it hard to believe they were hand edits, but I don't see how!
  2. I need to determine the current processes mach task/port info which is available as an extern variable in the mach_init.h, accessing it via cgo is straightforward, but I assume we do not want to use cgo for this. I haven't been able to figure out how to get go assembly to refer to a variable defined in a library, or rather all my variations of go:cgp_import_dynamic have failed. Do you have any suggestions for this?
    Thanks for the help with this!

@ianlancetaylor
Copy link
Contributor

@cosnicolaou I'm sorry to say that in the runtime package it's pretty much hand-editing these days for new constants and types. Getting back to a sane state is #23341.

@cosnicolaou
Copy link
Contributor

@ianlancetaylor thanks for responding so quickly! I'll just hand edit things which is fine, since it's not a lot of code. Do you have any suggestions for 2? Thanks!

@ianlancetaylor
Copy link
Contributor

You need to access a global variable defined in C code that is always linked in? Is that correct? And there is no C function that returns the value?

I'm not sure that a go:linkname directive will work here. The best bet might be assembler code. But it sounds like you've already tried that. What goes wrong?

@cherrymui
Copy link
Member

For 2, I think cgo_import_dynamic is the right answer. Currently I think most use cases are for functions, not variables. So it is possible that the linker just doesn't handle variables well. I can take a look.

@cosnicolaou
Copy link
Contributor

cosnicolaou commented Jun 7, 2023 via email

@ianlancetaylor
Copy link
Contributor

I don't know if this is the problem, but in this line:

MOVD mach_task_self_<>+0(SB), R0

you don't want the <> there. I would write this more like

MOVD $mach_task_self_(SB), R0 # puts address of variable into R0
MOVD 0(R0), R0 #load value of variable into R0

@cherrymui
Copy link
Member

I took a look at the linker code and I think we just don't handle cgo_import_dynamic for variables well (because we never needed it before). I'll see if I can make the linker handle this. Thanks.

@cosnicolaou
Copy link
Contributor

Ah yes, Ian's suggestion that definitely helps - I forgot to remove the <> when trying out different data approaches. Now I get the error below:
main.mach_task_self: program too large, address relocation distance = -4295532544

Which digging into the linker shows that a value is never set for the external symbol which could be because either it doesn't exist or the linker doesn't handle variables as well as functions for the cgo pragmas. Sounds like the latter. I extracted the libraries from the shared cache and found that this symbol is defined in the lowest level dyld library rather than libSystem (see below), but making that change to the cgo_import doesn't help, so I think it is the linker.

$nm ./libraries/usr/lib/dyld | grep mach_task_self
00000001db3ff6f0 s mach_task_self

@cherrymui
Copy link
Member

Yeah, it misses some case in the linker. The patch below seems to make it work:

diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index c91e37584c..0a76c71dc5 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -38,6 +38,7 @@ import (
        "cmd/link/internal/sym"
        "debug/elf"
        "log"
+       "fmt"
 )
 
 func PADDR(x uint32) uint32 {
@@ -251,6 +252,20 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
                        // nothing to do, the relocation will be laid out in reloc
                        return true
                }
+               if r.Type() == objabi.R_PCREL && ldr.SymType(s) == sym.STEXT && target.IsDarwin() {
+                       fmt.Println("XXX adddynrel", ldr.SymName(s), ldr.SymName(targ))
+                       ld.AddGotSym(target, ldr, syms, targ, 0)
+                       // turn LEAQ symbol address to MOVQ of GOT entry
+                       su := ldr.MakeSymbolUpdater(s)
+                       if r.Off() >= 2 && su.Data()[r.Off()-2] == 0x8d {
+                               su.MakeWritable()
+                               su.Data()[r.Off()-2] = 0x8b
+                               su.SetRelocSym(rIdx, syms.GOT)
+                               su.SetRelocAdd(rIdx, int64(ldr.SymGot(targ)))
+                               return true
+                       }
+                       log.Fatal("R_PCREL reloc to SDYNIMPORT symbol not preceded by LEAQ instruction")
+               }
                if target.IsExternal() {
                        // External linker will do this relocation.
                        return true

(Currently AMD64 internal linking mode only. I still need to do external linking mode (i.e. linking with cgo) and ARM64.)

With this patch, this seems to work: in Go, add

//go:cgo_import_dynamic libc_mach_task_self_ mach_task_self_ "/usr/lib/libSystem.B.dylib"

and in assembly,

	MOVQ	$libc_mach_task_self_(SB), AX
	MOVQ	(AX), AX
	MOVQ	AX, ret+0(FP)

Thanks.

@cherrymui
Copy link
Member

diff --git a/src/cmd/link/internal/amd64/asm.go b/src/cmd/link/internal/amd64/asm.go
index c91e37584c..b6aae0039a 100644
--- a/src/cmd/link/internal/amd64/asm.go
+++ b/src/cmd/link/internal/amd64/asm.go
@@ -38,6 +38,7 @@ import (
        "cmd/link/internal/sym"
        "debug/elf"
        "log"
+       "fmt"
 )
 
 func PADDR(x uint32) uint32 {
@@ -251,6 +252,24 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
                        // nothing to do, the relocation will be laid out in reloc
                        return true
                }
+               if r.Type() == objabi.R_PCREL && ldr.SymType(s) == sym.STEXT && target.IsDarwin() {
+                       fmt.Println("XXX adddynrel", ldr.SymName(s), ldr.SymName(targ))
+                       // turn LEAQ symbol address to MOVQ of GOT entry
+                       su := ldr.MakeSymbolUpdater(s)
+                       if r.Off() >= 2 && su.Data()[r.Off()-2] == 0x8d {
+                               su.MakeWritable()
+                               su.Data()[r.Off()-2] = 0x8b
+                               if target.IsInternal() {
+                                       ld.AddGotSym(target, ldr, syms, targ, 0)
+                                       su.SetRelocSym(rIdx, syms.GOT)
+                                       su.SetRelocAdd(rIdx, int64(ldr.SymGot(targ)))
+                               } else {
+                                       su.SetRelocType(rIdx, objabi.R_GOTPCREL)
+                               }
+                               return true
+                       }
+                       log.Fatal("R_PCREL reloc to SDYNIMPORT symbol not preceded by LEAQ instruction")
+               }
                if target.IsExternal() {
                        // External linker will do this relocation.
                        return true

This should handle external linking. Still need to do ARM64. Thanks.

@cosnicolaou
Copy link
Contributor

ok, I don't have access to an intel mac right now so I tried the above in the arm64/asm.go. Unfortunately, I think a larger change is required. adddynrel is called for the symbol main.get_mach_task_self and a targ of libc_mach_task_self, but the type of the relocation is R_ADDRARM64 which is not caught by any of the switch arms in adddynrel. Note that main.get_mach_task_self is the function that references the variable. Hope this helps!

@cherrymui
Copy link
Member

cherrymui commented Jun 8, 2023

@cosnicolaou this is the ARM64 version. It has different relocation types and instructions. Hopefully this will work. Thanks!

diff --git a/src/cmd/link/internal/arm64/asm.go b/src/cmd/link/internal/arm64/asm.go
index 312ee27aa6..88ead8d897 100644
--- a/src/cmd/link/internal/arm64/asm.go
+++ b/src/cmd/link/internal/arm64/asm.go
@@ -306,6 +306,36 @@ func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loade
                su.SetRelocAdd(rIdx, int64(ldr.SymPlt(targ)))
                return true
 
+       case objabi.R_ADDRARM64:
+               if targType == sym.SDYNIMPORT && ldr.SymType(s) == sym.STEXT && target.IsDarwin() {
+                       fmt.Println("XXX adddynrel", ldr.SymName(s), ldr.SymName(targ))
+                       // turn MOVD $sym (adrp+add) into MOVD sym@GOT (adrp+ldr)
+                       su := ldr.MakeSymbolUpdater(s)
+                       data := ldr.Data(s)
+                       off := r.Off()
+                       if int(off+8) > len(data) {
+                               ldr.Errorf(s, "unexpected R_ADDRARM64 reloc for dynamic symbol %s", ldr.SymName(targ))
+                               return false
+                       }
+                       o := target.Arch.ByteOrder.Uint32(data[off+4:])
+                       if o>>24 == 0x91 { // add
+                               // rewrite to ldr
+                               o = (0xf9 << 24) | 1<<22 | (o & (1<<22 - 1))
+                               su.MakeWritable()
+                               su.SetUint32(target.Arch, int64(off+4), o)
+                               if target.IsInternal() {
+                                       ld.AddGotSym(target, ldr, syms, targ, 0)
+                                       su.SetRelocSym(rIdx, syms.GOT)
+                                       su.SetRelocAdd(rIdx, int64(ldr.SymGot(targ)))
+                                       su.SetRelocType(rIdx, objabi.R_ARM64_PCREL_LDST64)
+                               } else {
+                                       su.SetRelocType(rIdx, objabi.R_ARM64_GOTPCREL)
+                               }
+                               return true
+                       }
+                       ldr.Errorf(s, "unexpected R_ADDRARM64 reloc for dynamic symbol %s", ldr.SymName(targ))
+               }
+
        case objabi.R_ADDR:
                if ldr.SymType(s) == sym.STEXT && target.IsElf() {
                        // The code is asking for the address of an external

I'll clean it up and turn it into a CL. Thanks.

@cosnicolaou
Copy link
Contributor

Yep - it does indeed work for arm64! Thanks! I'll try the intel version when I get back home in a week or so and have access to an intel mbp.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/501855 mentions this issue: cmd/link: handle dynamic import variables on Darwin

@cosnicolaou
Copy link
Contributor

FYI, I have the arm version of vm_region_info working. What are your plans for merging the linker changes and how should I construct the PRs for my changes - i.e. would you like to see one PR with the mach_vm_region assembly code and a second one with the pprof mapping changes, or would you prefer one? I would assume one, but lmk.

@cherrymui
Copy link
Member

This is great! Thanks.

We are currently in the freeze for Go 1.21 release, so I have to wait for the tree opens (probably late July) then I can submit the linker CL. (In the meantime, feel free to copy that code into your CL, if that's easier for you.)

For your change, yeah, a single CL is fine. Thanks.

@cosnicolaou
Copy link
Contributor

Take a look at https://go-review.googlesource.com/c/go/+/503919 when you have a moment, it includes your changes too.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/503919 mentions this issue: runtime,runtime/pprof: fixes support for assembler output

@prattmic prattmic changed the title cmd/pprof: disasm not working cmd/pprof: disasm not working on darwin Jun 28, 2023
gopherbot pushed a commit that referenced this issue Jul 20, 2023
Currently, on darwin, we only support cgo_dynamic_import for
functions, but not variables, as we don't need it before.
mach_task_self_ is a variable defined in the system library, which
can be used to e.g. access the process's memory mappings via the
mach API. The C header defines a macro mach_task_self(), which
refers to the variable. To use mach_task_self_ (in pure-Go
programs) we need to access it in Go.

This CL handles cgo_dynamic_import for variables in the linker,
loading its address via the GOT. (Currently only on Darwin, as
we only need it there.)

For #50891.

Change-Id: Idf64fa88ba2f2381443a1ed0b42b14b581843493
Reviewed-on: https://go-review.googlesource.com/c/go/+/501855
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/516156 mentions this issue: runtime/pprof: correct field alignment in machVMRegionBasicInfoData

gopherbot pushed a commit that referenced this issue Aug 4, 2023
The type machVMRegionBasicInfoData is generated from C type
vm_region_basic_info_data_64_t, which is a packed struct with a
64-bit field at offset 20. We cannot use uint64 as the field type
in the Go struct, as that will be aligned at offset 24, which does
not match the C struct. Change back to [8]byte (which is what the
cgo command generates), but keep the name Offset.

Updates #61707.
Updates #50891.

Change-Id: I2932328d7f9dfe9d79cff89752666c794d4d3788
Reviewed-on: https://go-review.googlesource.com/c/go/+/516156
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/518315 mentions this issue: runtime/pprof: don't run TestVMInfo on ios

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/546475 mentions this issue: doc: add release notes for runtime/pprof changes

gopherbot pushed a commit that referenced this issue Dec 4, 2023
For #50891.
For #61015.

For #61422.

Change-Id: I30d580814ac02fe9f3fbd1a101b2cc05947a9aaa
Reviewed-on: https://go-review.googlesource.com/c/go/+/546475
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
ezz-no pushed a commit to ezz-no/go-ezzno that referenced this issue Feb 18, 2024
For golang#50891.
For golang#61015.

For golang#61422.

Change-Id: I30d580814ac02fe9f3fbd1a101b2cc05947a9aaa
Reviewed-on: https://go-review.googlesource.com/c/go/+/546475
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/592499 mentions this issue: cmd/link: handle dynamic import variables on Darwin in plugin mode

gopherbot pushed a commit that referenced this issue Jun 22, 2024
CL 501855 added support for cgo_dynamic_import variables on Darwin.
But it didn't support the plugin build mode on amd64, where the
assembler turns a direct load (R_PCREL) to a load via GOT
(R_GOTPCREL). This CL adds the support. We just need to handle
external linking mode, as this can only occur in plugin or shared
build mode, which requires external linking.

Fixes #67976.
Updates #50891.

Change-Id: I0f56265d50bfcb36047fa5538ad7a5ec77e7ef96
Reviewed-on: https://go-review.googlesource.com/c/go/+/592499
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/595175 mentions this issue: [release-branch.go1.22] cmd/link: handle dynamic import variables on Darwin in plugin mode

gopherbot pushed a commit that referenced this issue Jun 26, 2024
…Darwin in plugin mode

CL 501855 added support for cgo_dynamic_import variables on Darwin.
But it didn't support the plugin build mode on amd64, where the
assembler turns a direct load (R_PCREL) to a load via GOT
(R_GOTPCREL). This CL adds the support. We just need to handle
external linking mode, as this can only occur in plugin or shared
build mode, which requires external linking.

Fixes #68122.
Updates #67976.
Updates #50891.

Change-Id: I0f56265d50bfcb36047fa5538ad7a5ec77e7ef96
Reviewed-on: https://go-review.googlesource.com/c/go/+/592499
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
(cherry picked from commit 44f1870)
Reviewed-on: https://go-review.googlesource.com/c/go/+/595175
Reviewed-by: Joedian Reid <joedian@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Mchnan pushed a commit to Mchnan/go-sylixos that referenced this issue Jul 9, 2024
CL 501855 added support for cgo_dynamic_import variables on Darwin.
But it didn't support the plugin build mode on amd64, where the
assembler turns a direct load (R_PCREL) to a load via GOT
(R_GOTPCREL). This CL adds the support. We just need to handle
external linking mode, as this can only occur in plugin or shared
build mode, which requires external linking.

Fixes golang#67976.
Updates golang#50891.

Change-Id: I0f56265d50bfcb36047fa5538ad7a5ec77e7ef96
Reviewed-on: https://go-review.googlesource.com/c/go/+/592499
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix The path to resolution is known, but the work has not been done. OS-Darwin
Projects
None yet
Development

No branches or pull requests