当运行我的Go程序时,它会死机并返回以下内容:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x38 pc=0x26df]
goroutine 1 [running]:
main.getBody(0x1cdcd4, 0xf800000004, 0x1f2b44, 0x23, 0xf84005c800, ...)
/Users/matt/Dropbox/code/go/scripts/cron/fido.go:65 +0x2bb
main.getToken(0xf84005c7e0, 0x10)
/Users/matt/Dropbox/code/go/scripts/cron/fido.go:140 +0x156
main.main()
/Users/matt/Dropbox/code/go/scripts/cron/fido.go:178 +0x61
goroutine 2 [syscall]:
created by runtime.main
/usr/local/Cellar/go/1.0.3/src/pkg/runtime/proc.c:221
goroutine 3 [syscall]:
syscall.Syscall6()
/usr/local/Cellar/go/1.0.3/src/pkg/syscall/asm_darwin_amd64.s:38 +0x5
syscall.kevent(0x6, 0x0, 0x0, 0xf840085188, 0xa, ...)
/usr/local/Cellar/go/1.0.3/src/pkg/syscall/zsyscall_darwin_amd64.go:199 +0x88
syscall.Kevent(0xf800000006, 0x0, 0x0, 0xf840085188, 0xa0000000a, ...)
/usr/local/Cellar/go/1.0.3/src/pkg/syscall/syscall_bsd.go:546 +0xa4
net.(*pollster).WaitFD(0xf840085180, 0xf840059040, 0x0, 0x0, 0x0, ...)
/usr/local/Cellar/go/1.0.3/src/pkg/net/fd_darwin.go:96 +0x185
net.(*pollServer).Run(0xf840059040, 0x0)
/usr/local/Cellar/go/1.0.3/src/pkg/net/fd.go:236 +0xe4
created by net.newPollServer
/usr/local/Cellar/go/1.0.3/src/pkg/net/newpollserver.go:35 +0x382
字符串
我看过其他人对同样的异常的React,但看不到任何简单的东西(即。未处理的错误)。
我在一台不能访问代码中列出的API服务器的机器上运行它,但我希望它会返回一个适当的错误(因为我已经尝试捕获这种错误)。
package main
/*
Fido fetches the list of public images from the Glance server, captures the IDs of images with 'status': 'active' and then queues the images for pre-fetching with the Glance CLI utility `glance-cache-manage`. Once the images are added to the queue, `glance-cache-prefetcher` is called to actively fetch the queued images into the local compute nodes' image cache.
See http://docs.openstack.org/developer/glance/cache.html for further details on the Glance image cache.
*/
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
/*
"log"
"log/syslog"
*/
"net/http"
"os"
"os/exec"
)
func prefetchImages() error {
cmd := exec.Command("glance-cache-prefetcher")
err := cmd.Run()
if err != nil {
return fmt.Errorf("glance-cache-prefetcher failed to execute properly: %v", err)
}
return nil
}
func queueImages(hostname string, imageList []string) error {
for _, image := range imageList {
cmd := exec.Command("glance-cache-manage", "--host=", hostname, "queue-image", image)
err := cmd.Run()
if err != nil {
return fmt.Errorf("glance-cache-manage failed to execute properly: %v", err)
} else {
fmt.Printf("Image %s queued", image)
}
}
return nil
}
func getBody(method string, url string, headers map[string]string, body []byte) ([]byte, error) {
client := &http.Client{}
req, err := http.NewRequest(method, url, bytes.NewReader(body))
if err != nil {
return nil, err
}
for key, value := range headers {
req.Header.Add(key, value)
}
res, err := client.Do(req)
defer res.Body.Close()
if err != nil {
return nil, err
}
var bodyBytes []byte
if res.StatusCode == 200 {
bodyBytes, err = ioutil.ReadAll(res.Body)
} else if err != nil {
return nil, err
} else {
return nil, fmt.Errorf("The remote end did not return a HTTP 200 (OK) response.")
}
return bodyBytes, nil
}
func getImages(authToken string) ([]string, error) {
type GlanceDetailResponse struct {
Images []struct {
Name string `json:"name"`
Status string `json:"status"`
ID string `json:"id"`
}
}
method := "GET"
url := "http://192.168.1.2:9292/v1.1/images/detail"
headers := map[string]string{"X-Auth-Token": authToken}
bodyBytes, err := getBody(method, url, headers, nil)
if err != nil {
return nil, fmt.Errorf("unable to retrieve the response body from the Glance API server: %v", err)
}
var glance GlanceDetailResponse
err = json.Unmarshal(bodyBytes, &glance)
if err != nil {
return nil, fmt.Errorf("unable to parse the JSON response:", err)
}
imageList := make([]string, 10)
for _, image := range glance.Images {
if image.Status == "active" {
imageList = append(imageList, image.ID)
}
}
return imageList, nil
}
func getToken() (string, error) {
type TokenResponse struct {
Auth []struct {
Token struct {
Expires string `json:"expires"`
ID string `json:"id"`
}
}
}
method := "POST"
url := "http://192.168.1.2:5000/v2.0/tokens"
headers := map[string]string{"Content-type": "application/json"}
creds := []byte(`{"auth":{"passwordCredentials":{"username": "glance", "password":"<password>"}, "tenantId":"<tenantkeygoeshere>"}}`)
bodyBytes, err := getBody(method, url, headers, creds)
if err != nil {
return "", err
}
var keystone TokenResponse
err = json.Unmarshal(bodyBytes, &keystone)
if err != nil {
return "", err
}
authToken := string((keystone.Auth[0].Token.ID))
return authToken, nil
}
func main() {
/*
slog, err := syslog.New(syslog.LOG_ERR, "[fido]")
if err != nil {
log.Fatalf("unable to connect to syslog: %v", err)
os.Exit(1)
} else {
defer slog.Close()
}
*/
hostname, err := os.Hostname()
if err != nil {
// slog.Err("Hostname not captured")
os.Exit(1)
}
authToken, err := getToken()
if err != nil {
// slog.Err("The authentication token from the Glance API server was not retrieved")
os.Exit(1)
}
imageList, err := getImages(authToken)
err = queueImages(hostname, imageList)
if err != nil {
// slog.Err("Could not queue the images for pre-fetching")
os.Exit(1)
}
err = prefetchImages()
if err != nil {
// slog.Err("Could not queue the images for pre-fetching")
os.Exit(1)
}
return
}
型
6条答案
按热度按时间6bc51xsx1#
根据
func (*Client) Do
的文档:然后看看这段代码:
字符串
err
不是nil
。在检查err
之前,您正在访问res.Body
上的.Close()
方法。defer
只延迟函数调用。立即访问该字段和方法。因此,请尝试立即检查错误。
型
lymnna712#
nil指针解引用在第65行,这是
字符串
如果err!= nil,则res==nil,并且res.Body会死机。在延迟res.Body之前处理err.Close()。
z2acfund3#
既然我带着我的问题来到这里,我将添加这个答案,尽管它与原来的问题不完全相关。当你实现一个接口时,确保不要忘记在你的成员函数声明中添加类型指针。范例:
字符串
我忘记了**(狗**狗)**部分,我不推荐它。然后,当在
Dog
类型的AnimalSounder
接口变量上调用MakeNoise
时,就会遇到麻烦。3z6pesqy4#
非常常见的用例
错误:
第一个月
可能由多种原因引起,所有这些原因最终都与内存分配有关。
我将添加另一个非常常见的用例(但对于初学者来说并不简单),这个错误可能会发生:
单元测试。
如果你正在为一个特定的函数编写一个单元测试,它引用了一个在函数外部初始化的变量**。
当你尝试测试这个函数时,你会得到panic错误。
示例
例如,名为
ValidateTag
的函数在第三方验证库中有依赖项:字符串
我们可以看到,
validator
结构应该在ValidateTag
之外初始化,因为它在主代码中的多个地方使用。失败
因此,如果我们的测试函数不会初始化
validator
结构:型
我们将得到无效内存地址错误。
工作中
在这里,我们导入相关的验证库并初始化在目标函数外部分配的变量:
型
0dxa2lsx5#
我知道这可能是一个编码问题,但对于其他人谁正在寻找另一个答案,问题是,我有程序运行在powershell和关闭powershell没有杀死进程。进程使用相同的端口,因此出现与上述相同的错误。我必须手动杀死进程,然后它工作正常。
pxq42qpu6#
确保通过发送返回值来处理所有错误。
字符串