Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

panic: runtime error: invalid memory address or nil pointer dereference #12

Open
wencan opened this issue Dec 4, 2018 · 1 comment
Open

Comments

@wencan
Copy link

wencan commented Dec 4, 2018

go run 下面的代码,触发该bug

package main

import (
	"fmt"
    "net/http"
    "os"
    "log"
	"github.com/ssgo/s"
)

func main() {
	 os.Setenv("SERVICE_APP", "s1")
	 os.Setenv("service_LOGFILE", os.DevNull)
	 os.Setenv("SERVICE_LISTEN", ":8080")
	 s.Restful(0, http.MethodGet, "/hello/{name}", func(args map[string]interface{}, w http.ResponseWriter, r *http.Request) {
	 	fmt.Fprintln(os.Stdout, args)
	 	log.Println(r.URL.Path)
	 	fmt.Fprintf(w, "Hello world\n")
	 })
	 s.Start1()
}

输出的错误信息:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x7ce6a6]

goroutine 1 [running]:
github.com/ssgo/s.start(0x1, 0x0, 0x0, 0xc0000e3f88)
	/home/wencan/Projects/Go/src/github.com/ssgo/s/Server.go:426 +0x27c6
github.com/ssgo/s.Start1()
	/home/wencan/Projects/Go/src/github.com/ssgo/s/Server.go:116 +0x33
main.main()
	/home/wencan/Projects/main.go:20 +0xff
exit status 2

源码分析:

	if err != nil {
		Error("S", Map{
			"subLogType": "server",
			"type":       "listenFailed",
			"listen":     config.Listen,
			"error":      err.Error(),
		})
		//log.Print("SERVER	", err)
		if as != nil {
			as.startChan <- false
		}
		return err
	}

        // 这里,err == nil

	closeChan := make(chan os.Signal, 2)
	signal.Notify(closeChan, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-closeChan
		listener.Close()
	}()

	addrInfo := listener.Addr().(*net.TCPAddr)
	ip := addrInfo.IP
	port := addrInfo.Port
	if !ip.IsGlobalUnicast() {
		// 如果监听的不是外部IP,使用第一个外部IP
		addrs, _ := net.InterfaceAddrs()
		for _, a := range addrs {
			an := a.(*net.IPNet)
			// 忽略 Docker 私有网段
			if an.IP.IsGlobalUnicast() && !strings.HasPrefix(an.IP.To4().String(), "172.17.") {
				ip = an.IP.To4()
			}
		}
	}
	serverAddr = fmt.Sprintf("%s:%d", ip.String(), port)

	dconf := discover.Config{
		Registry:             config.Registry,
		RegistryAllowTimeout: config.RegistryAllowTimeout,
		RegistryPrefix:       config.RegistryPrefix,
		RegistryCalls:        config.RegistryCalls,
		App:                  config.App,
		Weight:               config.Weight,
		CallRetryTimes:       config.CallRetryTimes,
		XUniqueId:            config.XUniqueId,
		XForwardedForName:    config.XForwardedForName,
		XRealIpName:          config.XRealIpName,
		CallTimeout:          config.CallTimeout,
	}
	calls := map[string]*discover.CallInfo{}
	if config.Calls == nil {
		config.Calls = map[string]*Call{}
	}
	for k, v := range config.Calls {
		call := discover.CallInfo{
			Timeout:     v.Timeout,
			HttpVersion: v.HttpVersion,
			WithSSL:     v.WithSSL,
		}
		call.Headers = map[string]string{}
		if v.AccessToken != "" {
			call.Headers["Access-Token"] = v.AccessToken
		}
		if v.Host != "" {
			call.Headers["Host"] = v.Host
		}
		calls[k] = &call
	}
	dconf.Calls = calls
	if discover.Start(serverAddr, dconf) == false {
		Error("S", Map{
			"subLogType": "server",
			"type":       "startDiscoverFailed",
			"serverAddr": serverAddr,
			"error":      err.Error(),     // panic: runtime error: invalid memory address or nil pointer dereference
		})
		//log.Printf("SERVER	failed to start discover")
		listener.Close()
		return errors.New("failed to start discover")
	}
@xujintao
Copy link
Contributor

xujintao commented Dec 5, 2018

os.Setenv("SERVICE_APP", "s1") 意味着以服务的方式启动,这种启动方式会把自己注册到redis,所以需要先启动redis。也可以把这一行注释掉,退化成普通后端。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants