Go运行时错误:恐慌:运行时错误:无效的内存地址或空指针解引用。

huangapple go评论69阅读模式
英文:

Go runtime error: panic: runtime error: invalid memory address or nil pointer dereference

问题

我的代码在几秒钟内正常运行,但之后会抛出一个错误:

panic: 运行时错误:无效的内存地址或空指针解引用

panic: 运行时错误:无效的内存地址或空指针解引用 [信号 SIGSEGV: 分段违规 code=0x1
addr=0x328 pc=0x58d086]

goroutine 1884 [正在运行]: crypto/tls.(*Conn).Close(0x0, 0x0, 0x0)
/usr/local/go/src/crypto/tls/conn.go:1310 +0x26 panic(0x5dcc60, 0x73dc30)
/usr/local/go/src/runtime/panic.go:965 +0x1b9 crypto/tls.(*Conn).Write(0x0, 0xc000701fb0, 0x23, 0x30, 0x0, 0x0, 0x0)
/usr/local/go/src/crypto/tls/conn.go:1101 +0x66 main.main.func1(0xc0000aa270, 0xd, 0x60d313, 0x9)
/home/nt-user/workspace/Main.go:28 +0x19b created by main.main
/home/nt-user/workspace/Main.go:18 +0xbf exit status 2

package main

import (
    // "net"
    "time"
    "fmt"
    "crypto/tls"
)

func main() {
    var (
        targetHost = "网站URL"
        targetPort = "443"
        targetURL = targetHost + ":" + targetPort
    )
    for true {
        for i := 0; i < 500; i++ {
            go func() {
               var s, err = tls.Dial("tcp", targetURL, &tls.Config {
                   ServerName: targetHost,
                   InsecureSkipVerify: true,
               })
               if err != nil {
                   fmt.Println("连接到" + targetHost + "时出错")
               }
               defer s.Close()
               for i := 0; i < 100; i++ {
                   s.Write([]byte("GET / HTTP/1.1\r\nHost: " + targetHost + "\r\n\r\n"))
               }
            }()
        }
        time.Sleep(1 * time.Second)
    }
}

我该如何修复这个问题?

英文:

My code run normaly in a few second but after that, it throws an error:

> panic: runtime error: invalid memory address or nil pointer
> dereference
>
> panic: runtime error: invalid memory address or nil pointer
> dereference [signal SIGSEGV: segmentation violation code=0x1
> addr=0x328 pc=0x58d086]
>
> goroutine 1884 [running]: crypto/tls.(*Conn).Close(0x0, 0x0, 0x0)
> /usr/local/go/src/crypto/tls/conn.go:1310 +0x26 panic(0x5dcc60, 0x73dc30)
> /usr/local/go/src/runtime/panic.go:965 +0x1b9 crypto/tls.(*Conn).Write(0x0, 0xc000701fb0, 0x23, 0x30, 0x0, 0x0, 0x0)
> /usr/local/go/src/crypto/tls/conn.go:1101 +0x66 main.main.func1(0xc0000aa270, 0xd, 0x60d313, 0x9)
> /home/nt-user/workspace/Main.go:28 +0x19b created by main.main
> /home/nt-user/workspace/Main.go:18 +0xbf exit status 2

package main

import (
    //&quot;net&quot;
    &quot;time&quot;
    &quot;fmt&quot;
    &quot;crypto/tls&quot;
)

func main() {
    var (
        targetHost = &quot;Website URL&quot;
        targetPort = &quot;443&quot;
        targetURL = targetHost + &quot;:&quot; + targetPort
    )
    for true {
        for i := 0; i &lt; 500; i++ {
            go func() {
               var s, err = tls.Dial(&quot;tcp&quot;, targetURL, &amp;tls.Config {
                   ServerName: targetHost,
                   InsecureSkipVerify: true,
               })
               if err != nil {
                   fmt.Println(&quot;Error when connect to &quot; + targetHost)
               }
               defer s.Close()
               for i := 0; i &lt; 100; i++ {
                   s.Write([]byte(&quot;GET / HTTP/1.1\r\nHost: &quot; + targetHost + &quot;\r\n\r\n&quot;))
               }
            }()
        }
        time.Sleep(1 * time.Second)
    }
}

How can I fix it?

答案1

得分: 1

在你的go func中,在tls.Dial之后,如果出现错误,它将继续使用s.Write中的nil s。这就是为什么会发生panic。所以如果有错误,就返回。

               var s, err = tls.Dial("tcp", targetURL, &tls.Config {
                   ServerName: targetHost,
                   InsecureSkipVerify: true,
               })
               if err != nil {
                   fmt.Println("连接到" + targetHost + "时出错")
                   return //在这里返回,否则它会继续使用nil "s"
               }

我建议不要打印错误。你可以将错误记录在你喜欢的日志记录器中,或者将其发送到一个错误通道并单独处理错误。

英文:

In your go func, after tls.Dial, if it is getting error, it will continue and use nil s in s.Write. That's why panic happens. So return if there is an error.

               var s, err = tls.Dial(&quot;tcp&quot;, targetURL, &amp;tls.Config {
                   ServerName: targetHost,
                   InsecureSkipVerify: true,
               })
               if err != nil {
                   fmt.Println(&quot;Error when connect to &quot; + targetHost)
                   return //return here, otherwise it continues to use nil &quot;s&quot;
               }

I prefer not to print error. Log it in your preferred logger or send it to an error channel and handle errors separately.

答案2

得分: -1

让我知道这是否对你有帮助。

for i := 0; i < 500; i++ {
    go func() {
        var s, err = tls.Dial("tcp", targetURL, &tls.Config {
            ServerName: targetHost,
            InsecureSkipVerify: true,
        })
        defer s.Close() // 移动到这里
        if err != nil {
            fmt.Println("连接到" + targetHost + "时出错")
            return
        }
        
        for i := 0; i < 100; i++ {
            s.Write([]byte("GET / HTTP/1.1\r\nHost: " + targetHost + "\r\n\r\n"))
        }
    }()
    time.Sleep(1 * time.Second) // 延迟一段时间
}
英文:

Let me know if this helps you

for i := 0; i &lt; 500; i++ {
 go func() {
          var s, err = tls.Dial(&quot;tcp&quot;, targetURL, &amp;tls.Config {
                   ServerName: targetHost,
                   InsecureSkipVerify: true,
          })
          defer s.Close() // moved to here
          if err != nil {
            fmt.Println(&quot;Error when connect to &quot; + targetHost)
            return
          }
         
          for i := 0; i &lt; 100; i++ {
             s.Write([]byte(&quot;GET / HTTP/1.1\r\nHost: &quot; + targetHost + &quot;\r\n\r\n&quot;))
          }
       }()
  time.Sleep(1 * time.Second) // give some delay
}

huangapple
  • 本文由 发表于 2021年8月27日 11:16:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/68947623.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定