internal: support optional filter expression for debug.stacks (#23605)
* internal: support optional filter expression for debug.stacks * internal/debug: fix string regexp * internal/debug: support searching for line numbers too
This commit is contained in:
		
							
								
								
									
										1
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.mod
									
									
									
									
									
								
							| @@ -35,6 +35,7 @@ require ( | ||||
| 	github.com/google/uuid v1.1.5 | ||||
| 	github.com/gorilla/websocket v1.4.2 | ||||
| 	github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 | ||||
| 	github.com/hashicorp/go-bexpr v0.1.10 // indirect | ||||
| 	github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d | ||||
| 	github.com/holiman/bloomfilter/v2 v2.0.3 | ||||
| 	github.com/holiman/uint256 v1.2.0 | ||||
|   | ||||
							
								
								
									
										6
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.sum
									
									
									
									
									
								
							| @@ -216,6 +216,8 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U | ||||
| github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= | ||||
| github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29 h1:sezaKhEfPFg8W0Enm61B9Gs911H8iesGY5R8NDPtd1M= | ||||
| github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= | ||||
| github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= | ||||
| github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= | ||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= | ||||
| @@ -307,6 +309,10 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m | ||||
| github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= | ||||
| github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||||
| github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= | ||||
| github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | ||||
| github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= | ||||
| github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= | ||||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||
| github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||||
| github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= | ||||
|   | ||||
| @@ -27,6 +27,7 @@ import ( | ||||
| 	"os" | ||||
| 	"os/user" | ||||
| 	"path/filepath" | ||||
| 	"regexp" | ||||
| 	"runtime" | ||||
| 	"runtime/debug" | ||||
| 	"runtime/pprof" | ||||
| @@ -35,6 +36,7 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/ethereum/go-ethereum/log" | ||||
| 	"github.com/hashicorp/go-bexpr" | ||||
| ) | ||||
|  | ||||
| // Handler is the global debugging handler. | ||||
| @@ -189,10 +191,44 @@ func (*HandlerT) WriteMemProfile(file string) error { | ||||
| 	return writeProfile("heap", file) | ||||
| } | ||||
|  | ||||
| // Stacks returns a printed representation of the stacks of all goroutines. | ||||
| func (*HandlerT) Stacks() string { | ||||
| // Stacks returns a printed representation of the stacks of all goroutines. It | ||||
| // also permits the following optional filters to be used: | ||||
| //   - filter: boolean expression of packages to filter for | ||||
| func (*HandlerT) Stacks(filter *string) string { | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	pprof.Lookup("goroutine").WriteTo(buf, 2) | ||||
|  | ||||
| 	// If any filtering was requested, execute them now | ||||
| 	if filter != nil && len(*filter) > 0 { | ||||
| 		expanded := *filter | ||||
|  | ||||
| 		// The input filter is a logical expression of package names. Transform | ||||
| 		// it into a proper boolean expression that can be fed into a parser and | ||||
| 		// interpreter: | ||||
| 		// | ||||
| 		// E.g. (eth || snap) && !p2p -> (eth in Value || snap in Value) && p2p not in Value | ||||
| 		expanded = regexp.MustCompile("[:/\\.A-Za-z0-9_-]+").ReplaceAllString(expanded, "`$0` in Value") | ||||
| 		expanded = regexp.MustCompile("!(`[:/\\.A-Za-z0-9_-]+`)").ReplaceAllString(expanded, "$1 not") | ||||
| 		expanded = strings.Replace(expanded, "||", "or", -1) | ||||
| 		expanded = strings.Replace(expanded, "&&", "and", -1) | ||||
| 		log.Info("Expanded filter expression", "filter", *filter, "expanded", expanded) | ||||
|  | ||||
| 		expr, err := bexpr.CreateEvaluator(expanded) | ||||
| 		if err != nil { | ||||
| 			log.Error("Failed to parse filter expression", "expanded", expanded, "err", err) | ||||
| 			return "" | ||||
| 		} | ||||
| 		// Split the goroutine dump into segments and filter each | ||||
| 		dump := buf.String() | ||||
| 		buf.Reset() | ||||
|  | ||||
| 		for _, trace := range strings.Split(dump, "\n\n") { | ||||
| 			if ok, _ := expr.Evaluate(map[string]string{"Value": trace}); ok { | ||||
| 				buf.WriteString(trace) | ||||
| 				buf.WriteString("\n\n") | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return buf.String() | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -278,7 +278,8 @@ web3._extend({ | ||||
| 		new web3._extend.Method({ | ||||
| 			name: 'stacks', | ||||
| 			call: 'debug_stacks', | ||||
| 			params: 0, | ||||
| 			params: 1, | ||||
| 			inputFormatter: [null], | ||||
| 			outputFormatter: console.log | ||||
| 		}), | ||||
| 		new web3._extend.Method({ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user