mirror of
https://github.com/golang/go
synced 2024-11-11 19:31:37 -07:00
runtime: support all as parameter in gdb goroutine commands.
For example, can use `goroutine all bt` to dump all goroutines'
information.
Change-Id: I51b547c2b837913e4bdabf0f45b28f09250a3e34
GitHub-Last-Rev: d04dcd4f58
GitHub-Pull-Request: golang/go#26283
Reviewed-on: https://go-review.googlesource.com/c/go/+/122589
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
08b956f378
commit
8c1f78524e
@ -149,6 +149,9 @@ Inspecting goroutines:
|
||||
(gdb) <b>help goroutine</b></pre>
|
||||
For example:
|
||||
<pre>(gdb) <b>goroutine 12 bt</b></pre>
|
||||
You can inspect all goroutines by passing <code>all</code> instead of a specific goroutine's ID.
|
||||
For example:
|
||||
<pre>(gdb) <b>goroutine all bt</b></pre>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@ -511,6 +511,10 @@ class GoroutineCmd(gdb.Command):
|
||||
|
||||
Usage: (gdb) goroutine <goid> <gdbcmd>
|
||||
|
||||
You could pass "all" as <goid> to apply <gdbcmd> to all goroutines.
|
||||
|
||||
For example: (gdb) goroutine all <gdbcmd>
|
||||
|
||||
Note that it is ill-defined to modify state in the context of a goroutine.
|
||||
Restrict yourself to inspecting values.
|
||||
"""
|
||||
@ -519,9 +523,20 @@ class GoroutineCmd(gdb.Command):
|
||||
gdb.Command.__init__(self, "goroutine", gdb.COMMAND_STACK, gdb.COMPLETE_NONE)
|
||||
|
||||
def invoke(self, arg, _from_tty):
|
||||
goid, cmd = arg.split(None, 1)
|
||||
goid = gdb.parse_and_eval(goid)
|
||||
pc, sp = find_goroutine(int(goid))
|
||||
goid_str, cmd = arg.split(None, 1)
|
||||
goids = []
|
||||
|
||||
if goid_str == 'all':
|
||||
for ptr in SliceValue(gdb.parse_and_eval("'runtime.allgs'")):
|
||||
goids.append(int(ptr['goid']))
|
||||
else:
|
||||
goids = [int(gdb.parse_and_eval(goid_str))]
|
||||
|
||||
for goid in goids:
|
||||
self.invoke_per_goid(goid, cmd)
|
||||
|
||||
def invoke_per_goid(self, goid, cmd):
|
||||
pc, sp = find_goroutine(goid)
|
||||
if not pc:
|
||||
print("No such goroutine: ", goid)
|
||||
return
|
||||
|
@ -217,6 +217,9 @@ func testGdbPython(t *testing.T, cgo bool) {
|
||||
"-ex", "echo BEGIN goroutine 2 bt\n",
|
||||
"-ex", "goroutine 2 bt",
|
||||
"-ex", "echo END\n",
|
||||
"-ex", "echo BEGIN goroutine all bt\n",
|
||||
"-ex", "goroutine all bt",
|
||||
"-ex", "echo END\n",
|
||||
"-ex", "clear main.go:15", // clear the previous break point
|
||||
"-ex", fmt.Sprintf("br main.go:%d", nLines), // new break point at the end of main
|
||||
"-ex", "c",
|
||||
@ -303,6 +306,10 @@ func testGdbPython(t *testing.T, cgo bool) {
|
||||
t.Fatalf("goroutine 2 bt failed: %s", bl)
|
||||
}
|
||||
|
||||
if bl := blocks["goroutine all bt"]; !btGoroutine1Re.MatchString(bl) || !btGoroutine2Re.MatchString(bl) {
|
||||
t.Fatalf("goroutine all bt failed: %s", bl)
|
||||
}
|
||||
|
||||
btGoroutine1AtTheEndRe := regexp.MustCompile(`(?m)^#0\s+(0x[0-9a-f]+\s+in\s+)?main\.main.+at`)
|
||||
if bl := blocks["goroutine 1 bt at the end"]; !btGoroutine1AtTheEndRe.MatchString(bl) {
|
||||
t.Fatalf("goroutine 1 bt at the end failed: %s", bl)
|
||||
|
Loading…
Reference in New Issue
Block a user