2012-08-23 308 views
0

作爲一項練習,我創建了一個小型HTTP服務器,可以生成隨機遊戲機制,類似於this one。我將它寫在Windows 7(32位)系統上,並且工作完美無瑕。但是,當我在我的家用機器Windows 7(64位)上運行它時,它總是失敗,並顯示相同的消息:exit status -1073741819。我還沒有設法找到引用該狀態碼的任何內容,所以我不知道它有多重要。什麼導致我的HTTP服務器失敗,並顯示「退出狀態-1073741819」?

下面是服務器代碼,具有冗餘刪節:

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) 
    } 
} 

此外,unabridged code_base.html templateindex.html template

什麼可能導致此問題?是否有像這樣調試隱藏退出狀態的過程?

+3

這是一個訪問衝突0000005的Windows代碼。我搜索了一下,發現了一些關於反病毒軟件和蠕蟲的抱怨。但是,您在32位和64位機器上提到了不同的行爲。您是否正在使用任何可能爲一個架構設計的二進制文件? –

+0

@RayToal不,我只使用了系統上編譯的每個二進制文件。運行編譯後的二進制文件時,我沒有收到退出狀態消息,但它以相同的方式失敗;我想這是因爲Windows的命令提示符沒有顯示退出狀態。當我使用'go run mechanics.go'時,go工具顯示退出狀態。編輯:我也嘗試禁用我的殺毒軟件,但我得到同樣的問題。 – Keeblebrox

回答

1

當我跑了,我得到了以下兩個錯誤:

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

前者是在Web瀏覽器,後者在我啓動服務器的控制檯窗口。

零指針問題是因爲您的刪節程序將GameMechanics [1:32]設置爲零。

第二個錯誤很有趣。在你的程序中,你的http.ResponseWriter中的任何方法被調用的唯一地方是index.Execute,而不是你的代碼 - 這意味着html/template中可能發生了錯誤。我正在用Go 1.0.2測試這個。

我把_base.html在index.html的頂部,然後改變指數這樣:

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

和http.WriteHeaders警告走了。

不是一個真正的答案,而是一個你可以探索的方向。

作爲獎勵,下面是編寫程序的「Go方式」。請注意,我簡化了使用PRNG(你不需要實例化,除非你想要去的幾個平行)的,簡化了結構初始化:

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) 
    } 
} 
+0

我喜歡你的初始化和生成方法!比我寫的要乾淨得多。當我運行它時,我仍然得到相同的退出狀態消息,但是'index.Execute'好像可能是源代碼;這比以前更好。 – Keeblebrox

相關問題