How can I get samples when running go with pkg/profile enabled? - go

I have the following in my main block:
func main() {
defer profile.Start().Stop()
fmt.Println("running version", version, "built on", date)
fmt.Println()
cmd.Execute()
time.Sleep(2 * time.Second)
}
where cmd is a cobra subcommand. I do a go build, and then I run the binary. I can see that it generates a pprof file:
2018/09/13 18:43:26 profile: cpu profiling enabled, /tmp/profile705487093/cpu.pprof
... output deleted ...
2018/09/13 18:43:31 profile: cpu profiling disabled, /tmp/profile705487093/cpu.pprof
Then I'm trying to analyze it, using:
go tool pprof /root/code/debug/evented /tmp/profile705487093/cpu.pprof
But when pprof opens, I see this:
File: evented
Type: cpu
Time: Sep 13, 2018 at 6:43pm (UTC)
Duration: 5.49s, Total samples = 0
In case it helps, I'm running go version go1.11 linux/amd64 on a Ubuntu 16.04.5 LTS. Not sure whether it matters, but I'm trying to inspect the pprof output on a DigitalOcean droplet.
Is there something that I'm doing wrong? Thanks!

After looking a bit through the comments of the profile pkg, I managed to get some samples, by doing this:
runtime.SetCPUProfileRate(5000)
before calling the defer profile.Start().Stop() line.

Related

A nil pointer panic occurs only in debug mode while calling fmt.Sprintf

What version of Go are you using (go version)?
$ go version
go version go1.18 darwin/amd64
What did you do?
I wrote some simple code below that it try to print a struct
import v1 "k8s.io/api/core/v1"
import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
func main() {
data := v1.Namespace{
ObjectMeta: metav1.ObjectMeta{
DeletionTimestamp: nil,
},
}
str := fmt.Sprintf("%#v", data)
fmt.Println(str)
}
What did you expect to see?
same behavior with or without debugger
What did you see instead?
I was intended to print a struct called Namespace which is defined in k8s.io/api/core/v1/types.go, when I run it simply in GoLand(GoLand 2021.3.4) without debug, it runs as expected and the structure of the object had been printed in the console, but when i run it also in Goland but with debug, the program had been interrupted by an error: "bad access: nil dereference". the call stack is:
<autogenerated>:2
fmt.(*pp).handleMethods (print.go:603) fmt
fmt.(*pp).printValue (print.go:723) fmt
fmt.(*pp).printValue (print.go:806) fmt
fmt.(*pp).printValue (print.go:806) fmt
fmt.(*pp).printArg (print.go:712) fmt
fmt.(*pp).doPrintf (print.go:1026) fmt
fmt.Sprintf (print.go:219) fmt
main.main (main.go:97) main
runtime.main (proc.go:250) runtime
runtime.goexit (asm_amd64.s:1571) runtime
- Async Stack Trace
<autogenerated>:2
this is a little bit weird: If this(panic) is a intented behavior, then how can it runs correctly without debugger?
I had the same problem. I tried to upgrade the mac os version, but it did not work.
The main reason is debugserver version,mine before version is:
/Library/Developer/CommandLineTools/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/debugserver --version
debugserver-#(#)PROGRAM:LLDB PROJECT:lldb-1205.0.27
and, later upgrade debugserver by:
sudo rm -rf /Library/Developer/CommandLineTools
and it will remain to intall again, and the latest version is:
debugserver-#(#)PROGRAM:LLDB PROJECT:lldb-1316.0.9.46
then, everything works.

How to find out time.Sleep() in the execution path?

Trying to find out time.Sleep() call in the execution path.
To simplify the problem, consider the code below.
func BenchmarkSleep(b *testing.B) {
for i:=0; i < b.N; i++ {
time.Sleep(time.Millisecond * 10)
}
}
I tried to profile (cpu, block, mutex) the code and expected to see the time.Sleep samples in the profile.
What should I do.
Have you tried:
go test -trace trace.out
followed by:
go tool trace trace.out
... to view it in a browser?
You can then generate a pprof-like profile from the trace:
go tool trace -pprof=TYPE trace.out > TYPE.pprof
Supported profile types are:
net: network blocking profile
sync: synchronization blocking profile
syscall: syscall blocking profile
sched: scheduler latency profile
And view that too:
go tool pprof TYPE.pprof
More generally...
The trace package: https://golang.org/pkg/runtime/trace/
Can be used with the trace tool: https://golang.org/cmd/trace/
To get diagnostics and visualise the profiling data: https://golang.org/doc/diagnostics.html

go commands run slow on my windows machine, and fine on my linux

I don't know if someone else is running into this problem. I have this main.go file:
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
when I run go build, it takes 5 secs to run it (regardless if it is the first time I run it or if it is the second time)
PS> Measure-Command {Start-Process go build -wait}
Days : 0
Hours : 0
Minutes : 0
Seconds : 5
Milliseconds : 151
Ticks : 51514117
TotalDays : 5.96228206018519E-05
TotalHours : 0.00143094769444444
TotalMinutes : 0.0858568616666667
TotalSeconds : 5.1514117
TotalMilliseconds : 5151.4117
But when I run it on a linux machine:
time go build
real 0m2.017s
user 0m0.054s
sys 0m1.915s
and when I run it for the second time:
time go build
real 0m0.120s
user 0m0.072s
sys 0m0.088s
This is not only build, but also some of go tools such as fmt. It takes 0.12 seconds on linux, but almost 3 seconds on windows. Other tools like guru, gocode, etc. suffer the same problem, making code development very slow.
I'm using golang 1.11. I'm using an SSD and everything is running locally. Sorry I wish I could be more helpful but I really have no idea where to start to debug this.
Does anyone has an idea what's going on?
It seems that the build cache is disabled on your Windows and enabled on your Linux.
Go build keeps the result of compilations and reuse it if the .go file hasn't changed. That's why your second build is so fast in Linux.
If you disable it, not only your code, but also all the dependancies must be recompiled each time. Thus even if you change your code, all the libs (here "fmt") are already in cache.
To test it, run go clean -cache before the go build on Linux, and see if the time correspond to the time on your Windows. Then if it matches, you have to find why the build cache is disabled on Windows.
You can see the cache directory by typing go env GOCACHE. If the response is off, the cache is off. Otherwise verify that the repository exists and it has the right permissions.
You can choos the cache directory by setting the value of the GOCACHE environment variable (sorry I don't know how to do this in Windows).
I was having same issue. Turns out I had a really big directory with 1000s of large files in the same location where the binary was. Moving the big dir out to a different location resolved the issue. This was in a macOS.

Go plugin core dumps when using go routines and variables

I am unable to use variables inside my go routine started in a go plugin.
The following code is an example of what I am trying to do.
The code
// Can be an non-empty struct as well
var channel = make(chan string)
log.Println(channel)
go func(ch chan string) {
log.Println(ch)
}(channel)
crahes with a coredump when executed in a go plugin on darwin.
-Yes Go plugins work on darwin: http://prntscr.com/iq8czy
I recently reported this issue to golang: Issue related to go plugin crashes
This only appears to be the case on darwin (OS X).

Cross compile net/http for distribution

I have build the following code in a docker container with the following architecture:
cat /proc/version
Linux version 3.16.7-tinycore64 (root#064f0e1ce709) (gcc version 4.7.2 (Debian 4.7.2-5) ) #1 SMP Tue Dec 16 23:03:39 UTC 2014
package main
import "fmt"
func main() {
fmt.Println("Hello")
}
The binary distributed, runs with no problem on a busybox container, with the same architecture without installing golang.
The problem
When I do the same for the following code:
package main
import (
"fmt"
"net/http"
)
const (
port = ":80"
)
var calls = 0
func HelloWorld(w http.ResponseWriter, r *http.Request) {
calls++
fmt.Fprintf(w, "Hello, world! You have called me %d times.\n", calls)
}
func init() {
fmt.Printf("Started server at http://localhost%v.\n", port)
http.HandleFunc("/", HelloWorld)
http.ListenAndServe(port, nil)
}
func main() {}
Then I get:
ash: ./hello_world: not found
I might be missing some dependencies - like "net/http"?
But I thought the go build would build all into the binaries.
This is for both go build & go install.
Any idea?
The answer is most probably the one described in this article.
Some critical parts of the standard library use CGO [...] if you cross-compile Go to Darwin or Linux your programs won’t use the system DNS resolver. They also can’t use the native host certificate store. They also can’t look up the user’s home directory, either.
And CGO links against some standard system interfaces by default, dynamically.
The article suggests using gonative to fix the problem. If that's not your cup of tea, some people suggest using:
go build -ldflags "-linkmode external -extldflags -static"
Also read: https://groups.google.com/d/topic/golang-nuts/H-NTwhQVp-8/discussion
I think you need to disable cgo and build with netgo flag :
The net package requires cgo by default because the host operating
system must in general mediate network call setup. On some systems,
though, it is possible to use the network without cgo, and useful to
do so, for instance to avoid dynamic linking. The new build tag netgo
(off by default) allows the construction of a net package in pure Go
on those systems where it is possible.
The netgo tag requires version 1.2 and above.

Resources