什么导致我的HTTP服务器出现“退出状态-1073741819”失败?

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

What is causing my HTTP server to fail with "exit status -1073741819"?

问题

作为练习,我创建了一个小型的HTTP服务器,用于生成随机游戏机制,类似于这个。我在Windows 7(32位)系统上编写它,并且它可以完美运行。然而,当我在家里的机器上运行它时,Windows 7(64位),它总是以相同的消息失败:exit status -1073741819。我还没有找到任何关于该状态码的网络参考,所以我不知道它有多重要。

这是服务器的代码,省略了冗余部分:

package main

import (
    "fmt"
    "math/rand"
    "time"
    "net/http"
    "html/template"
)

// 游戏机制的信息
type MechanicInfo struct { Name, Desc string }

// 将机制打印为字符串
func (m MechanicInfo) String() string {
    return fmt.Sprintf("%s: %s", m.Name, m.Desc)
}

// 一个可能的游戏机制
var (
    UnkillableObjects = &MechanicInfo{"避免不可杀死的物体",
                                      "有些物体玩家不能触碰。它们与普通敌人不同,因为它们不能被销毁或移动。"}
    //...
    Race              = &MechanicInfo{"竞赛",
                                      "玩家必须在对手之前到达一个地方。类似于“计时”,但敌人作为“计时器”可以被玩家的行动减慢,或者可能有多个敌人与之竞争。"}
)

// 包含所有游戏机制的切片
var GameMechanics []*MechanicInfo

// 伪随机数生成器
var prng *rand.Rand

// 获取一个随机机制
func RandMechanic() *MechanicInfo {
    i := prng.Intn(len(GameMechanics))
    return GameMechanics[i]
}


// 初始化包
func init() {
    prng = rand.New(rand.NewSource(time.Now().Unix()))
    
    GameMechanics = make([]*MechanicInfo, 34)
    GameMechanics[0] = UnkillableObjects
    //...
    GameMechanics[33] = Race
}

// 服务

var index = template.Must(template.ParseFiles(
    "templates/_base.html",
    "templates/index.html",
))

func randMechHandler(w http.ResponseWriter, req *http.Request) {
    mechanics := [3]*MechanicInfo{RandMechanic(), RandMechanic(), RandMechanic()}
    if err := index.Execute(w, mechanics); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func main() {
    http.HandleFunc("/", randMechHandler)
    if err := http.ListenAndServe(":80", nil); err != nil {
        panic(err)
    }
}

此外,还有完整的代码_base.html模板index.html模板

可能是什么原因导致了这个问题?有没有一种调试这种加密的退出状态的过程?

英文:

As an exercise I created a small HTTP server that generates random game mechanics, similar to this one. I wrote it on a Windows 7 (32-bit) system and it works flawlessly. However, when I run it on my home machine, Windows 7 (64-bit), it always fails with the same message: exit status -1073741819. I haven't managed to find anything on the web which references that status code, so I don't know how important it is.

Here's code for the server, with redundancy abridged:

package main

import (
    "fmt"
    "math/rand"
    "time"
    "net/http"
    "html/template"
)

// Info about a game mechanic
type MechanicInfo struct { Name, Desc string }

// Print a mechanic as a string
func (m MechanicInfo) String() string {
    return fmt.Sprintf("%s: %s", m.Name, m.Desc)
}

// A possible game mechanic
var (
    UnkillableObjects = &MechanicInfo{"Avoiding Unkillable Objects",
                                      "There are objects that the player cannot touch. These are different from normal enemies because they cannot be destroyed or moved."}
    //...
    Race              = &MechanicInfo{"Race",
                                      "The player must reach a place before the opponent does. Like \"Timed\" except the enemy as a \"timer\" can be slowed down by the player's actions, or there may be multiple enemies being raced against."}
)

// Slice containing all game mechanics
var GameMechanics []*MechanicInfo

// Pseudorandom number generator
var prng *rand.Rand

// Get a random mechanic
func RandMechanic() *MechanicInfo {
    i := prng.Intn(len(GameMechanics))
    return GameMechanics[i]
}


// Initialize the package
func init() {
    prng = rand.New(rand.NewSource(time.Now().Unix()))
    
    GameMechanics = make([]*MechanicInfo, 34)
    GameMechanics[0] = UnkillableObjects
    //...
    GameMechanics[33] = Race
}

// serving

var index = template.Must(template.ParseFiles(
    "templates/_base.html",
    "templates/index.html",
))

func randMechHandler(w http.ResponseWriter, req *http.Request) {
    mechanics := [3]*MechanicInfo{RandMechanic(), RandMechanic(), RandMechanic()}
    if err := index.Execute(w, mechanics); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}

func main() {
    http.HandleFunc("/", randMechHandler)
    if err := http.ListenAndServe(":80", nil); err != nil {
        panic(err)
    }
}

In addition, the unabridged code, the _base.html template, and the index.html template.

What could be causing this issue? Is there a process for debugging a cryptic exit status like this?

答案1

得分: 1

当我运行它时,我得到了以下两个错误:

template: content:6: nil pointer evaluating *main.MechanicInfo.Name
http: multiple response.WriteHeader calls

前者出现在Web浏览器中,后者出现在我启动服务器的控制台窗口中。

空指针问题是因为你的简化程序将GameMechanics[1:32]设置为nil。

第二个错误很有趣。你的程序中唯一调用http.ResponseWriter上的任何方法的地方是在index.Execute内部,而这不是你的代码 - 这意味着可能在html/template中发生了一些错误。我正在使用Go 1.0.2进行测试。

我将_base.html放在index.html的顶部,然后将index更改为以下内容:

var index = template.Must(template.ParseFiles("templates/index.html"))

然后http.WriteHeaders的警告消失了。

这不是一个真正的答案,但是你可以探索的一个方向。

作为奖励,这是更“Go方式”的编写程序的方法。请注意,我简化了PRNG的使用(除非你想要并行运行多个),并简化了结构初始化器:

package main

import (
	"fmt"
	"html/template"
	"math/rand"
	"net/http"
)

// 游戏机制的信息
type MechanicInfo struct{ Name, Desc string }

// 将机制打印为字符串
func (m MechanicInfo) String() string {
	return fmt.Sprintf("%s: %s", m.Name, m.Desc)
}

// 游戏机制
var GameMechanics = [...]*MechanicInfo{
	{"避免无法杀死的物体",
		"有些物体玩家不能触碰。它们与普通敌人不同,因为它们不能被销毁或移动。"},
	{"竞赛",
		"玩家必须在对手之前到达一个地方。类似于“计时”,但敌人作为“计时器”可以被玩家的行动减慢,或者可能有多个敌人与之竞争。"},
}

// 获取一个随机机制
func RandMechanic() *MechanicInfo {
	i := rand.Intn(len(GameMechanics))
	return GameMechanics[i]
}

var index = template.Must(template.ParseFiles("templates/index.html"))

func randMechHandler(w http.ResponseWriter, req *http.Request) {
	mechanics := [3]*MechanicInfo{RandMechanic(), RandMechanic(), RandMechanic()}
	if err := index.Execute(w, mechanics); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func main() {
	http.HandleFunc("/", randMechHandler)
	if err := http.ListenAndServe(":80", nil); err != nil {
		panic(err)
	}
}
英文:

When I ran it, I got the following two errors:

template: content:6: nil pointer evaluating *main.MechanicInfo.Name
http: multiple response.WriteHeader calls

The former was in the web browser, the latter in the console window where I launched your server.

The nil pointer problem is because your abridged program leaves GameMechanics[1:32] set to nil.

The second error is interesting. The only place in your program that any methods on your http.ResponseWriter get called is inside of index.Execute, which is not your code -- meaning maybe there is something wrong happening in html/template. I'm testing this with Go 1.0.2.

I put _base.html at the top of index.html and then changed index to this:

var index = template.Must(template.ParseFiles("templates/index.html"))

and the http.WriteHeaders warning went away.

Not really an answer, but a direction you could explore.

As a bonus, here's the more "Go way" of writing your program. Note that I simplified the use of the PRNG (you don't need to instantiate unless you want several going in parallel) and simplified the structure initializer:

package main

import (
	"fmt"
	"html/template"
	"math/rand"
	"net/http"
)

// Info about a game mechanic
type MechanicInfo struct{ Name, Desc string }

// Print a mechanic as a string
func (m MechanicInfo) String() string {
	return fmt.Sprintf("%s: %s", m.Name, m.Desc)
}

// The game mechanics
var GameMechanics = [...]*MechanicInfo{
	{"Avoiding Unkillable Objects",
		"There are objects that the player cannot touch. These are different from normal enemies because they cannot be destroyed or moved."},
	{"Race",
		"The player must reach a place before the opponent does. Like \"Timed\" except the enemy as a \"timer\" can be slowed down by the player's actions, or there may be multiple enemies being raced against."},
}

// Get a random mechanic
func RandMechanic() *MechanicInfo {
	i := rand.Intn(len(GameMechanics))
	return GameMechanics[i]
}

var index = template.Must(template.ParseFiles("templates/index.html"))

func randMechHandler(w http.ResponseWriter, req *http.Request) {
	mechanics := [3]*MechanicInfo{RandMechanic(), RandMechanic(), RandMechanic()}
	if err := index.Execute(w, mechanics); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func main() {
	http.HandleFunc("/", randMechHandler)
	if err := http.ListenAndServe(":80", nil); err != nil {
		panic(err)
	}
}

huangapple
  • 本文由 发表于 2012年8月24日 04:58:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/12099880.html
匿名

发表评论

匿名网友

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

确定