Understanding panic output in the Go language

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed. My code has a bug.? ' panic:runtime error:invalid memory address or nil pointer dereference[signal sigsegv:segmentation viola tion code=0x1 addr=0x30 pc=0x751ba4]goroutine [Running]:github.com/joeshaw/example. Updateresponse (0XAD3C60, 0xc420257300, 0xc4201f4200, 0x16, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, ...)/go/src/github.com/joeshaw/ example/resp.go:108 +0x144github.com/joeshaw/example. Prefetchloop (0xacfd60, 0xc420395480, 0x13a52453c000, 0xad3c60, 0xc420257300)/go/src/github.com/joeshaw/example/ resp.go:82 +0xc00created by main.runserver/go/src/github.com/joeshaw/example/cmd/server/server.go:100 +0x7e0 ' ' This The panic error is caused by the dereference of a nil pointer, as indicated in the first line of the output. Because of the syntax of go in error handling, these types of errors are less common in go than in other languages such as C or Java. This type of error is much less in go than in other languages such as C or Java, thanks to the error handling of go. If a function fails, the function must return an ' error ' as its last return value. The caller should immediately check the error returned by the function. "' go//Val is a pointer, err was an error interface Valueval, err: = Somethingthatcouldfail () if err! = Nil {//Deal with The error, probably PushinG it up the call stack return err}//by convention, nearly all the time, Val was guaranteed to not be//nil here. "However, it must Somewhere there is a bug (panic), which violates the convention of this implicit API. Before I dive in, here's an additional note: This is about architecture and operating system, and I'm only running on AMD64 Linux and MacOS. Other system operation results should be different. The second line of the panic error output gives information about the UNIX signal triggering this panic: ' [signal sigsegv:segmentation violation code=0x1 addr=0x30 PC=0X751BA4] ' because A nil pointer was dereferenced and a segment error occurred (SIGSEGV). The ' Code ' area is mapped to the ' siginfo.si_cod ' area of UNIX, and the ' 0x1 ' value in Linux ' siginfo.h ' is ' segv_maperr ' (the address is not mapped to an object). ' Addr ' maps to ' siginfo.si_addr ', whose value is ' 0x30 ', which is not a valid memory address. ' PC ' is a program counter that we can use to find out where the program crashed, but we don't usually need to do this because a goroutine trace has the following information. "Goroutine [Running]:github.com/joeshaw/example]. Updateresponse (0XAD3C60, 0xc420257300, 0xc4201f4200, 0x16, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, ...)/go/src/github.com/joeshaw/ example/resp.go:108 +0x144github.com/joeshaw/example. Prefetchloop (0xacfd60, 0xc420395480, 0x13a52453c000, 0xad3c60, 0xc420257300)/go/src/github.com/joeshaw/example/ resp.go:82 +0xc00created by Main.runserVer/go/src/github.com/joeshaw/example/cmd/server/server.go:100 +0x7e0 "In this deep stack frame, the first one that causes the panic to occur (the file) is listed first. In this example, there are 108 lines of the ' resp.go ' file. In this goroutine backtracking message, what catches my eye is the parameters of the function ' updateresponse ' and ' Prefetchloop ', because the number does not match the function signature. "' Gofunc updateresponse (c Client, id string, version int, resp *response, data []byte] Errorfunc Prefetchloop (CTX context . Context, Interval time. Duration, C Client) ' Updateresponse ' requires 5 parameters, but panic shows that it carries more than 10 parameters. ' Prefetchloop ' requires 3 parameters, but panic shows it has 5 parameters. What's going to happen? To understand the parameter values, we have to understand some data structures about the Go underlying type. Russcox has two great blogs, one on [basic type, struct and pointer, string and slice] (https://research.swtch.com/godata), and another on [interface] (https:// Research.swtch.com/interfaces), which describes how these are distributed in memory. For Go programmers, these two articles are essential readings, but they are summed up as follows:-The string has two fields (a pointer to the string data and a length)-The slice has three fields (a pointer to the underlying array, a length, a capacity)-the interface has two fields (a pointer to a type and a pointer to a value When panic occurs, we see that the parameter values in the output include the exported values for strings, slices, and interfaces. In addition, the return value of the function is added to the end of the parameter list. Back to our ' updateresponse ' function, the ' Client ' type is an interface with 2 values. ' ID ' is a string that has 2 values (4 total). ' Version ' is an integer with 1 values (a total of 5 values). ' RESP ' is a pointer with 1 values (a total of 6). ' DaTa ' is a slice with 3 values (a total of 9 values). The ' ERROR ' return value is an interface, so there are 2 more values, resulting in a total of 11. The panic output has a limit of 10, so the last value is truncated in the output. This is a annotated ' updateresponse ' stack frame: ' Github.com/joeshaw/example. Updateresponse (0XAD3C60,//C Client interface, type pointer 0xc420257300,//C Client interface, value pointer 0xc4201f4 $,//ID string, data pointer 0x16,//ID string, Length (0x16 = $) 0x1,//version int (1) 0x0,//RESP pointer (nil!) 0x0,//Data slice, backing array pointer (nil) 0x0,//Data slice, Length (0) 0x0,//Data slice, capacity (0) 0x0,//E Rror interface (return value), type pointer ...//truncated; Would has been error interface value pointer) "This helps to confirm the source's suggestion that ' resp ' is ' nil ' and it is dereferenced. Move up one stack frame to ' prefetchloop ': ' CTX context. Context ' is an interface value, ' interval ' is a ' time. Duration ' (It's just a ' int64 '), ' Client ' is also an interface. The ' Prefetchloop ' comment is: ' Github.com/joeshaw/example. Prefetchloop (0XACFD60,//CTX context.) Context interface, type pointer 0xc420395480,//CTX context. Context interface, value pointer 0x13a52453c000,//InTerval time. Duration (6h0m) 0XAD3C60,//C Client interface, type pointer 0xc420257300,//C Client interface, value pointer) "' As I have the premise , ' resp ' should not be ' nil ' because it only happens when the error is not ' nil '. The culprit is that the ' WRAPF () ' function of ' github.com/pkg/errors ' is used incorrectly in the code instead of ' Errorf () '. "' go//Function Returns (*response, []byte, error) if resp. StatusCode! = http. Statusok {return nil, nil, errors. WRAPF (Err, "Got status code%d fetching response%s", resp. StatusCode, URL)} "if the first parameter of ' WRAPF () ' is passed to ' nil ', its return value is ' nil '. When this HTTP status code is not ' HTTP '. Statusok ', this function will incorrectly return ' Nil,nil,nil ' because a non-200 status code is not an error, so the value of ' err ' is ' nil '. Will ' errors. WRAPF () ' Call replaced with ' errors. Errorf () ' Can fix this bug. Understanding and combining contextual context panic output can be easier to track down to errors! Hope this information will be useful to you in the future. Thanks to Peter Teichman, Damian Gryski, and Travis Bischel, they helped me to analyze the output parameter list of panic.

via:https://joeshaw.org/understanding-go-panic-output/

Author: Joe Shaw Translator: liuxinyu123 proofreading: polaris1119

This article by GCTT original compilation, go language Chinese network honor launches

This article was originally translated by GCTT and the Go Language Chinese network. Also want to join the ranks of translators, for open source to do some of their own contribution? Welcome to join Gctt!
Translation work and translations are published only for the purpose of learning and communication, translation work in accordance with the provisions of the CC-BY-NC-SA agreement, if our work has violated your interests, please contact us promptly.
Welcome to the CC-BY-NC-SA agreement, please mark and keep the original/translation link and author/translator information in the text.
The article only represents the author's knowledge and views, if there are different points of view, please line up downstairs to spit groove

3,752 Reads
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.