preface
When the GO code is running, it may produce panic because the code is not robust as a whole. If panic is not recovered, the whole process will exit. We often need to analyze the code through the function stack that Panic throws to find the panic location
This article will cover how the same GO code behaves in GO1.16 and go1.17. The reason for using both versions is that in 1.17, go introduced a major update. Instead of just passing arguments in memory, functions are called using registers first and memory later
code
package main
func main(a) {
getPanic([]string{"get"."panic"}, 0x1234)}//go:noinline
func getPanic(p1 []string, p2 int) string {
panic("paniced")
return "panic"
}
Copy the code
NOTE: // Gonoinline adds this line to prevent simple functions from being optimized inline
Let’s take a look at go1.16
panic: paniced
goroutine 1 [running]:
main.getPanic(0xc000046758, 0x2, 0x2, 0x1234, 0xc00006a058, 0x1013201)
/Users/holen/main.go:9 +0x39
main.main()
/Users/holen/main.go:4 +0x7d
exit status 2
Copy the code
The first thing we know is that the bottom of each stack is where each goroutine starts, and in this case, there’s only one goroutine, which is the main routine
And then look down from the top
* /Users/holen/main.go:9 * /Users/holen/main.go:9 * /Users/holen/main.go:9 * /Users/holen/main.go:9 * /Users/holen/main.go:9
It is the input parameter and return value of the getPanic function. Some people may wonder if the parameter + return value is not three parameters, why there are six parameters
0xC000046758, 0x2, 0x2 => [] String {"get","panic"} 0x1234 => 0x1234 0xC00006A058, 0x1013201 => Returned valueCopy the code
In Golang, slice is composed of three members: slice address, length and capacity, and string is composed of two elements: string address and length
Then take a look at the performance of GO1.17
panic: paniced goroutine 1 [running]: main.getPanic({0xc000048770, 0x1004319, 0x60}, 0x0) /Users/holen/main.go:9 +0x27 main.main() /Users/holen/main.go:4 +0x65 exit Status 2 The Shell returns 1Copy the code
Comparison with GO1.16 is not hard to find
- There are three values
{}
The parcel - Missing some parameters
- The values displayed do not seem to match the parameters
Indeed, go has been optimized in 1.17 for the display of stack information. Instead of laying out all the information, go will use {} groups to indicate that these are three elements of one parameter. Secondly, there are fewer return value parameters, which is actually the same problem with question 3. It is all caused by the change of the parameter transfer convention in the function call of go in 1.17. Therefore, these parameters are actually in the register, so the display is not correct