Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions runtime_patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,12 +267,10 @@ func stripRuntime(basename string, file *ast.File) (strippedFunctions map[string
funcDecl.Body.List = nil
}
case "runtime1.go":
switch funcDecl.Name.Name {
case "setTraceback":
// tracebacks are completely hidden, no
// sense keeping this function
funcDecl.Body.List = nil
}
// setTraceback is deliberately left alone. Besides selecting how
// much of a traceback is printed, it decides whether fatal errors
// crash the process rather than exiting with status 2, and it
// enables Windows Error Reporting for GOTRACEBACK=wer.
case "runtime.go":
// writeErrStr bypasses the print builtins and writes fixed fatal
// diagnostics straight to stderr (and SetCrashOutput). Tiny mode
Expand Down
42 changes: 42 additions & 0 deletions testdata/script/tiny.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ stderr '^makefunc.name reflect\.makeFuncStub value 107$'
stderr '^methodvalue.name reflect\.methodValueCall value 213$'
stderr '^wrapper.name _\.\(\*_\)\._ recovered true$'
stderr '^runtime.sentinels.goexit true gopanic true$'
# GOTRACEBACK controls more than traceback output, which tiny mode hides:
# "crash" must still crash the process rather than exit with status 2.
stderr '^single aborts: false crash aborts: true$'

[short] stop # no need to verify this with -short

Expand All @@ -48,20 +51,40 @@ stderr '^makefunc.name reflect\.makeFuncStub value 107$'
stderr '^methodvalue.name reflect\.methodValueCall value 213$'
stderr '^wrapper.name .* recovered true$'
stderr '^runtime.sentinels.goexit true gopanic true$'
stderr '^single aborts: false crash aborts: true$'
-- go.mod --
module test/main

go 1.23
-- main_linux.go --
package main

import "syscall"

// Keep the crashing children from writing core dumps.
// Note that syscall.Rlimit is only declared in some unix GOOSes.
func init() {
var lim syscall.Rlimit
if syscall.Getrlimit(syscall.RLIMIT_CORE, &lim) == nil {
lim.Cur = 0
syscall.Setrlimit(syscall.RLIMIT_CORE, &lim)
}
}
-- garble_main.go --
package main

import (
cryptorand "crypto/rand"
"os"
"os/exec"
"reflect"
"runtime"
"runtime/debug"
"sync"
)

var nilPtr *int

type testStruct struct{}

func (testStruct) unexportedFunc() { println("dummy") }
Expand Down Expand Up @@ -156,7 +179,26 @@ func checkRuntimeConsumedNames() {
println("runtime.sentinels.goexit", <-goexit, "gopanic", gopanic)
}

// childAborts reports whether a nil dereference at the given GOTRACEBACK level
// kills this program rather than exiting with the usual status 2. Only
// runtime.setTraceback records that setting, so tiny mode must not empty it.
func childAborts(level string) bool {
self, err := os.Executable()
if err != nil {
panic(err)
}
cmd := exec.Command(self, level)
cmd.Run()
return cmd.ProcessState.ExitCode() != 2
}

func main() {
if len(os.Args) > 1 {
debug.SetTraceback(os.Args[1])
println(*nilPtr)
}
println("single aborts:", childAborts("single"), "crash aborts:", childAborts("crash"))

checkRuntimeConsumedNames()

// Retain fatal paths which Go 1.26 moved into runtime-linked standard
Expand Down
Loading