From 78d5f264b493f125018180c204871ecf58a2dce1 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Sun, 29 Apr 2018 18:56:08 +1000 Subject: [PATCH] windows/svc: correct MOVL instruction in sys_amd64.s Second argument of servicemain is a pointer. See https://msdn.microsoft.com/en-us/library/windows/desktop/ms685138(v=vs.85).aspx So amd64 assembler code should use MOVQ to read that value. I probably copied 386 assembler code into amd64 and did not adjust the code. Broken code was used to pass parameters to the service, so add some tests to verify that parameter passing works. Fixes golang/go#24575 Change-Id: I89f8cad026ea13f8a5d78ff3e24b7236e27fc91f Reviewed-on: https://go-review.googlesource.com/110160 Run-TryBot: Alex Brainman TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- windows/svc/example/service.go | 2 ++ windows/svc/svc_test.go | 19 ++++++++++++++++++- windows/svc/sys_amd64.s | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/windows/svc/example/service.go b/windows/svc/example/service.go index 237e8098..74c93930 100644 --- a/windows/svc/example/service.go +++ b/windows/svc/example/service.go @@ -8,6 +8,7 @@ package main import ( "fmt" + "strings" "time" "golang.org/x/sys/windows/svc" @@ -26,6 +27,7 @@ func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes c slowtick := time.Tick(2 * time.Second) tick := fasttick changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} + elog.Info(1, strings.Join(args, "-")) loop: for { select { diff --git a/windows/svc/svc_test.go b/windows/svc/svc_test.go index da7ec666..60eb4478 100644 --- a/windows/svc/svc_test.go +++ b/windows/svc/svc_test.go @@ -7,10 +7,13 @@ package svc_test import ( + "fmt" "io/ioutil" + "math/rand" "os" "os/exec" "path/filepath" + "strings" "testing" "time" @@ -86,8 +89,10 @@ func TestExample(t *testing.T) { } defer s.Close() + args := []string{"is", "manual-started", fmt.Sprintf("%d", rand.Int())} + testState(t, s, svc.Stopped) - err = s.Start("is", "manual-started") + err = s.Start(args...) if err != nil { t.Fatalf("Start(%s) failed: %s", s.Name, err) } @@ -115,4 +120,16 @@ func TestExample(t *testing.T) { if err != nil { t.Fatalf("Delete failed: %s", err) } + + cmd := `Get-Eventlog -LogName Application -Newest 100` + + ` | Where Source -eq "myservice"` + + ` | Select -first 10` + + ` | Format-table -HideTableHeaders -property ReplacementStrings` + out, err := exec.Command("powershell", "-Command", cmd).CombinedOutput() + if err != nil { + t.Fatalf("powershell failed: %v\n%v", err, string(out)) + } + if want := strings.Join(append([]string{name}, args...), "-"); !strings.Contains(string(out), want) { + t.Errorf("%q string does not contain %q", string(out), want) + } } diff --git a/windows/svc/sys_amd64.s b/windows/svc/sys_amd64.s index 06b42590..bde25e9c 100644 --- a/windows/svc/sys_amd64.s +++ b/windows/svc/sys_amd64.s @@ -7,7 +7,7 @@ // func servicemain(argc uint32, argv **uint16) TEXT ·servicemain(SB),7,$0 MOVL CX, ·sArgc(SB) - MOVL DX, ·sArgv(SB) + MOVQ DX, ·sArgv(SB) SUBQ $32, SP // stack for the first 4 syscall params