move gochan & golang stuff over
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
796d07652e
commit
bd33b5649e
|
@ -0,0 +1,100 @@
|
|||
// https://www.digitalocean.com/community/tutorials/how-to-run-multiple-functions-concurrently-in-go
|
||||
// who came up with the idea of making community tutorials. that was a good idea!
|
||||
|
||||
package debugger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/gui/gui"
|
||||
)
|
||||
|
||||
var debugWG *sync.WaitGroup
|
||||
var debugNumberChan chan int
|
||||
|
||||
func DebugGoChannels(n *gui.Node) {
|
||||
var w, g *gui.Node
|
||||
|
||||
w = n.NewWindow("Debug GO Channels")
|
||||
w.Custom = w.StandardClose
|
||||
|
||||
g = w.NewGroup("Channel stuff")
|
||||
|
||||
// var debugWG sync.WaitGroup
|
||||
g.NewButton("init()", func () {
|
||||
if (debugNumberChan == nil) {
|
||||
log.Log(true, "making debugNumberChan channel")
|
||||
debugNumberChan = make(chan int)
|
||||
} else {
|
||||
log.Log(true, "debugNumberChan already made")
|
||||
}
|
||||
debugWG = new(sync.WaitGroup)
|
||||
})
|
||||
g.NewButton("go printInt(x) (read x values off the channel)", func () {
|
||||
debugWG.Add(1)
|
||||
go printInt(2, "routine1")
|
||||
debugWG.Add(1)
|
||||
go printInt(2, "routine2")
|
||||
})
|
||||
g.NewButton("sendNumber(2) (chan <- 2, 4)", func () {
|
||||
debugWG.Add(1)
|
||||
debugWG.Add(1)
|
||||
go sendNumber(2)
|
||||
go sendNumber(4)
|
||||
})
|
||||
g.NewButton("sendNumber(1) (chan <- 7)", func () {
|
||||
debugWG.Add(1)
|
||||
go sendNumber(7)
|
||||
})
|
||||
g.NewButton("send 4 numbers (chan <- int)", func () {
|
||||
log.Log(true, "generateNumbers(4)")
|
||||
go generateNumbers(4)
|
||||
})
|
||||
g.NewButton("debugWG.Done()", func () {
|
||||
log.Log(true, "ran debugWG.Done()")
|
||||
debugWG.Done()
|
||||
})
|
||||
g.NewButton("close chan", func () {
|
||||
log.Log(true, "close() on", debugNumberChan)
|
||||
close(debugNumberChan)
|
||||
})
|
||||
g.NewButton("print", func () {
|
||||
log.Log(true, "waitgroup counter is ?")
|
||||
})
|
||||
}
|
||||
func sendNumber(i int) {
|
||||
log.Log(true, "START debugNumberChan <-", i, " (sending", i, "to channel)")
|
||||
debugNumberChan <- i
|
||||
debugWG.Wait()
|
||||
log.Log(true, "END debugNumberChan sendNumber() done", i)
|
||||
}
|
||||
|
||||
func generateNumbers(total int) {
|
||||
fmt.Printf("START generateNumbers()\n")
|
||||
for idx := 1; idx <= total; idx++ {
|
||||
log.Log(true, "ran debugNumberChan <= idx where idx =", idx)
|
||||
fmt.Printf("S generateNumbers() sending %d to channel\n", idx)
|
||||
debugNumberChan <- idx
|
||||
// res, err := (<-r)()
|
||||
fmt.Printf("E generateNumbers() sending %d to channel\n", idx)
|
||||
}
|
||||
debugWG.Wait()
|
||||
fmt.Printf("END generateNumbers()\n")
|
||||
}
|
||||
|
||||
// i equals the number of times to read values from the channel
|
||||
func printInt(i int, name string) {
|
||||
tmp := 1
|
||||
log.Log(true, "START printInt", name, "read debugNumberChan()")
|
||||
for num := range debugNumberChan {
|
||||
log.Log(true, "printInt()",name, "read", num, "from channel")
|
||||
debugWG.Done()
|
||||
if (tmp == i) {
|
||||
return
|
||||
}
|
||||
tmp += 1
|
||||
}
|
||||
fmt.Printf("END printInt()", name, "read debugNumberChan\n")
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
package debugger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"bytes"
|
||||
// "os"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"runtime/pprof"
|
||||
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/gui/gui"
|
||||
)
|
||||
|
||||
func DebugGolangWindow(n *gui.Node) {
|
||||
var newW, newB, g, og, outputTextbox *gui.Node
|
||||
|
||||
newW = n.NewWindow("GO")
|
||||
newW.Custom = newW.StandardClose
|
||||
newB = newW.NewBox("hBox", true)
|
||||
|
||||
g = newB.NewGroup("Language Internals")
|
||||
|
||||
g.NewButton("ReadModuleInfo()", func () {
|
||||
tmp, _ := debug.ReadBuildInfo()
|
||||
outputTextbox.SetText(tmp.String())
|
||||
})
|
||||
g.NewButton("runtime.NumGoroutine()", func () {
|
||||
buf := new(bytes.Buffer)
|
||||
pprof.Lookup("goroutine").WriteTo(buf, 1)
|
||||
outputTextbox.SetText(buf.String())
|
||||
|
||||
outputTextbox.AppendText(fmt.Sprintln("runtime.NumGoroutine() = ", runtime.NumGoroutine()))
|
||||
})
|
||||
g.NewButton("pprof.Lookup(heap)", func () {
|
||||
buf := new(bytes.Buffer)
|
||||
pprof.Lookup("heap").WriteTo(buf, 1)
|
||||
outputTextbox.SetText(buf.String())
|
||||
})
|
||||
g.NewButton("debug.PrintStack(current)", func () {
|
||||
outputTextbox.SetText(string(debug.Stack()))
|
||||
})
|
||||
g.NewButton("pprof.Lookup(goroutine)", func () {
|
||||
buf := new(bytes.Buffer)
|
||||
pprof.Lookup("goroutine").WriteTo(buf, 1)
|
||||
outputTextbox.SetText(buf.String())
|
||||
})
|
||||
g.NewButton("pprof.Lookup(block)", func () {
|
||||
buf := new(bytes.Buffer)
|
||||
pprof.Lookup("block").WriteTo(buf, 1)
|
||||
outputTextbox.SetText(buf.String())
|
||||
})
|
||||
g.NewButton("pprof.Lookup threadcreate", func () {
|
||||
buf := new(bytes.Buffer)
|
||||
pprof.Lookup("threadcreate").WriteTo(buf, 1)
|
||||
outputTextbox.SetText(buf.String())
|
||||
})
|
||||
|
||||
g.NewButton("runtime.ReadMemStats()", func () {
|
||||
outputTextbox.SetText(runtimeReadMemStats())
|
||||
})
|
||||
|
||||
g.NewButton("debug.FreeOSMemory()", func () {
|
||||
var out string = "Before debug.FreeOSMemory():\n\n"
|
||||
out += runtimeReadMemStats()
|
||||
debug.FreeOSMemory()
|
||||
out += "\n\nAfter debug.FreeOSMemory():\n\n"
|
||||
out += runtimeReadMemStats()
|
||||
outputTextbox.SetText(out)
|
||||
})
|
||||
|
||||
g.NewButton("debug.ReadGCStats()", func () {
|
||||
var tmp debug.GCStats
|
||||
var out string
|
||||
debug.ReadGCStats(&tmp)
|
||||
log.Log(true, tmp)
|
||||
out += fmt.Sprintln("LastGC:", tmp.LastGC, "// time.Time time of last collection")
|
||||
out += fmt.Sprintln("NumGC:", tmp.NumGC, "// number of garbage collections")
|
||||
out += fmt.Sprintln("PauseTotal:", tmp.PauseTotal, "// total pause for all collections")
|
||||
out += fmt.Sprintln("Pause:", tmp.Pause, "// []time.Duration pause history, most recent first")
|
||||
out += fmt.Sprintln("PauseEnd:", tmp.Pause, "// []time.Time pause history, most recent first")
|
||||
out += fmt.Sprintln("PauseQuantiles:", tmp.PauseQuantiles, "// []time.Duration")
|
||||
outputTextbox.SetText(out)
|
||||
})
|
||||
|
||||
g.NewButton("debug.SetTraceback('all')", func () {
|
||||
debug.SetTraceback("all")
|
||||
})
|
||||
|
||||
g.NewButton("panic()", func () {
|
||||
panic("test")
|
||||
})
|
||||
|
||||
g = newB.NewGroup("TODO: finish these")
|
||||
|
||||
// g.NewLabel("TODO:")
|
||||
|
||||
g.NewButton("runtime.Stack(true)", func () {
|
||||
// TODO: https://stackoverflow.com/questions/61127053/how-to-list-all-the-running-goroutines-in-a-go-program
|
||||
// func Stack(buf []byte, all bool) int
|
||||
})
|
||||
|
||||
g.NewButton("debug.SetMemoryLimit(int)", func () {
|
||||
// TODO:
|
||||
//debug.SetMemoryLimit(1024 * 1024 * 100)
|
||||
})
|
||||
|
||||
g.NewButton("debug.SetMaxStack(int bytes)", func () {
|
||||
// default is apparently 1GB
|
||||
})
|
||||
|
||||
g.NewButton("debug.SetMaxThreads(int)", func () {
|
||||
// default is apparently 10,000
|
||||
})
|
||||
|
||||
g.NewButton("debug.SetTraceback('all')", func () {
|
||||
debug.SetTraceback("all")
|
||||
})
|
||||
|
||||
// deprecated (probably) by String() implementation within golang
|
||||
g.NewButton("dumpModuleInfo() (deprecate)", func () {
|
||||
outputTextbox.SetText(dumpModuleInfo())
|
||||
})
|
||||
|
||||
og = newB.NewGroup("output")
|
||||
outputTextbox = og.NewTextbox("outputBox")
|
||||
outputTextbox.Custom = func () {
|
||||
log.Log(true, "custom TextBox() for golang output a =", outputTextbox.S)
|
||||
}
|
||||
}
|
||||
|
||||
func runtimeReadMemStats() string {
|
||||
var s runtime.MemStats
|
||||
var out string
|
||||
runtime.ReadMemStats(&s)
|
||||
out += fmt.Sprintln("alloc:", s.Alloc, "bytes")
|
||||
out += fmt.Sprintln("total-alloc:", s.TotalAlloc, "bytes")
|
||||
out += fmt.Sprintln("sys:", s.Sys, "bytes")
|
||||
out += fmt.Sprintln("lookups:", s.Lookups)
|
||||
out += fmt.Sprintln("mallocs:", s.Mallocs)
|
||||
out += fmt.Sprintln("frees:", s.Frees)
|
||||
out += fmt.Sprintln("heap-alloc:", s.HeapAlloc, "bytes")
|
||||
out += fmt.Sprintln("heap-sys:", s.HeapSys, "bytes")
|
||||
out += fmt.Sprintln("heap-idle:", s.HeapIdle,"bytes")
|
||||
out += fmt.Sprintln("heap-in-use:", s.HeapInuse, "bytes")
|
||||
out += fmt.Sprintln("heap-released:", s.HeapReleased, "bytes")
|
||||
out += fmt.Sprintln("heap-objects:", s.HeapObjects)
|
||||
out += fmt.Sprintln("stack-in-use:", s.StackInuse, "bytes")
|
||||
out += fmt.Sprintln("stack-sys", s.StackSys, "bytes")
|
||||
out += fmt.Sprintln("next-gc: when heap-alloc >=", s.NextGC, "bytes")
|
||||
out += fmt.Sprintln("last-gc:", s.LastGC, "ns")
|
||||
out += fmt.Sprintln("gc-pause:", s.PauseTotalNs, "ns")
|
||||
out += fmt.Sprintln("num-gc:", s.NumGC)
|
||||
out += fmt.Sprintln("enable-gc:", s.EnableGC)
|
||||
out += fmt.Sprintln("debug-gc:", s.DebugGC)
|
||||
return out
|
||||
}
|
||||
|
||||
func dumpModuleInfo() string {
|
||||
var out string
|
||||
tmp, _ := debug.ReadBuildInfo()
|
||||
if tmp == nil {
|
||||
out += fmt.Sprintln("This wasn't compiled with go module support")
|
||||
return ""
|
||||
}
|
||||
out += fmt.Sprintln("mod.Path = ", tmp.Path)
|
||||
out += fmt.Sprintln("mod.Main.Path = ", tmp.Main.Path)
|
||||
out += fmt.Sprintln("mod.Main.Version = ", tmp.Main.Version)
|
||||
out += fmt.Sprintln("mod.Main.Sum = ", tmp.Main.Sum)
|
||||
for _, value := range tmp.Deps {
|
||||
out += fmt.Sprintln("\tmod.Path = ", value.Path)
|
||||
out += fmt.Sprintln("\tmod.Version = ", value.Version)
|
||||
}
|
||||
return out
|
||||
}
|
|
@ -50,10 +50,10 @@ func DebugWindow2(n *gui.Node, title string) *gui.Node {
|
|||
gui.DebugWidgetWindow(myGui)
|
||||
})
|
||||
gog.NewButton("GO Language Internals", func () {
|
||||
bugWin.DebugGolangWindow()
|
||||
DebugGolangWindow(bugWin)
|
||||
})
|
||||
gog.NewButton("GO Channels debug", func () {
|
||||
bugWin.DebugGoChannels()
|
||||
DebugGoChannels(bugWin)
|
||||
})
|
||||
|
||||
gog.NewLabel("Force Quit:")
|
||||
|
|
Loading…
Reference in New Issue