diff --git a/debug/gdebug/gdebug_caller.go b/debug/gdebug/gdebug_caller.go index dcad18a8a..e9b1ac70f 100644 --- a/debug/gdebug/gdebug_caller.go +++ b/debug/gdebug/gdebug_caller.go @@ -32,6 +32,9 @@ func init() { if goRootForFilter != "" { goRootForFilter = strings.ReplaceAll(goRootForFilter, "\\", "/") } + if len(os.Args) == 0 { + return + } // Initialize internal package variable: selfPath. selfPath, _ = exec.LookPath(os.Args[0]) if selfPath != "" { diff --git a/net/ghttp/ghttp_server_admin.go b/net/ghttp/ghttp_server_admin.go index 310841c28..4178a4ca8 100644 --- a/net/ghttp/ghttp_server_admin.go +++ b/net/ghttp/ghttp_server_admin.go @@ -8,7 +8,6 @@ package ghttp import ( "context" - "os" "strings" "time" @@ -59,7 +58,11 @@ func (p *utilAdmin) Restart(r *Request) { // Custom start binary path when this process exits. path := r.GetQuery("newExeFilePath").String() if path == "" { - path = os.Args[0] + path = gfile.SelfPath() + } + if path == "" { + r.Response.WriteExit("cannot determine current executable path") + return } if err = RestartAllServer(ctx, path); err == nil { r.Response.WriteExit("server restarted") diff --git a/net/ghttp/ghttp_server_admin_process.go b/net/ghttp/ghttp_server_admin_process.go index 60313218a..d71c20077 100644 --- a/net/ghttp/ghttp_server_admin_process.go +++ b/net/ghttp/ghttp_server_admin_process.go @@ -119,16 +119,25 @@ func checkActionFrequency() error { // forkReloadProcess creates a new child process and copies the fd to child process. func forkReloadProcess(ctx context.Context, newExeFilePath ...string) error { var ( - binaryPath = os.Args[0] + binaryPath = gfile.SelfPath() ) if len(newExeFilePath) > 0 && newExeFilePath[0] != "" { binaryPath = newExeFilePath[0] } + if binaryPath == "" { + return gerror.NewCodef( + gcode.CodeInvalidOperation, + "cannot determine current executable path: gfile.SelfPath() returned empty and no executable override was provided (goos=%s, goarch=%s, overrideProvided=%t)", + runtime.GOOS, + runtime.GOARCH, + len(newExeFilePath) > 0 && newExeFilePath[0] != "", + ) + } if !gfile.Exists(binaryPath) { return gerror.Newf(`binary file path "%s" does not exist`, binaryPath) } var ( - p = gproc.NewProcess(binaryPath, os.Args[1:], os.Environ()) + p = gproc.NewProcess(binaryPath, getCurrentProcessArgs(), os.Environ()) sfm = getServerFdMap() ) for name, m := range sfm { @@ -165,17 +174,20 @@ func forkReloadProcess(ctx context.Context, newExeFilePath ...string) error { // forkRestartProcess creates a new server process. func forkRestartProcess(ctx context.Context, newExeFilePath ...string) error { var ( - path = os.Args[0] + path = gfile.SelfPath() ) if len(newExeFilePath) > 0 && newExeFilePath[0] != "" { path = newExeFilePath[0] } + if path == "" { + return gerror.NewCode(gcode.CodeInvalidOperation, "cannot determine current executable path") + } if err := os.Unsetenv(adminActionReloadEnvKey); err != nil { intlog.Errorf(ctx, `%+v`, err) } env := os.Environ() env = append(env, adminActionRestartEnvKey+"=1") - p := gproc.NewProcess(path, os.Args[1:], env) + p := gproc.NewProcess(path, getCurrentProcessArgs(), env) if _, err := p.Start(ctx); err != nil { glog.Errorf( ctx, @@ -187,6 +199,13 @@ func forkRestartProcess(ctx context.Context, newExeFilePath ...string) error { return nil } +func getCurrentProcessArgs() []string { + if len(os.Args) > 1 { + return os.Args[1:] + } + return nil +} + // getServerFdMap returns all the servers name to file descriptor mapping as map. func getServerFdMap() map[string]listenerFdMap { sfm := make(map[string]listenerFdMap) diff --git a/os/gfile/gfile.go b/os/gfile/gfile.go index ee1c902f1..a4b70f28e 100644 --- a/os/gfile/gfile.go +++ b/os/gfile/gfile.go @@ -44,6 +44,9 @@ var ( ) func init() { + if len(os.Args) == 0 { + return + } // Initialize internal package variable: selfPath. selfPath, _ = exec.LookPath(os.Args[0]) if selfPath != "" {