CompilerBootstrap reports whether the current compiler binary was built with -tags=compiler_bootstrap.
const CompilerBootstrap = false
To enable tracing support (-t flag), set EnableTrace to true.
const EnableTrace = false
var AutogeneratedPos src.XPos
var Ctxt *obj.Link
DebugSSA is called to set a -d ssa/... option. If nil, those options are reported as invalid options. If DebugSSA returns a non-empty string, that text is reported as a compiler error.
var DebugSSA func(phase, flag string, val int, valString string) string
Pos is the current source position being processed, printed by Errorf, ErrorfLang, Fatalf, and Warnf.
var Pos src.XPos
ReservedImports are import paths used internally for generated symbols by the compiler.
The linker uses the magic symbol prefixes "go:" and "type:". Avoid potential confusion between import paths and symbols by rejecting these reserved imports for now. Also, people "can do weird things in GOPATH and we'd prefer they didn't do _that_ weird thing" (per rsc). See also #4257.
var ReservedImports = map[string]bool{ "go": true, "type": true, }
func AdjustStartingHeap(requestedHeapGoal uint64)
AdjustStartingHeap modifies GOGC so that GC should not occur until the heap grows to the requested size. This is intended but not promised, though it is true-mostly, depending on when the adjustment occurs and on the compiler's input and behavior. Once this size is approximately reached GOGC is reset to 100; subsequent GCs may reduce the heap below the requested size, but this function does not affect that.
-d=gcadjust=1 enables logging of GOGC adjustment events.
NOTE: If you think this code would help startup time in your own application and you decide to use it, please benchmark first to see if it actually works for you (it may not: the Go compiler is not typical), and whatever the outcome, please leave a comment on bug #56546. This code uses supported interfaces, but depends more than we like on current+observed behavior of the garbage collector, so if many people need this feature, we should consider/propose a better way to accomplish it.
func Assert(b bool)
Assert reports "assertion failed" with Fatalf, unless b is true.
func Assertf(b bool, format string, args ...interface{})
Assertf reports a fatal error with Fatalf, unless b is true.
func AssertfAt(b bool, pos src.XPos, format string, args ...interface{})
AssertfAt reports a fatal error with FatalfAt, unless b is true.
func AtExit(f func())
func DebugHashMatchPkgFunc(pkg, fn string) bool
DebugHashMatchPkgFunc reports whether debug variable Gossahash
is empty (returns true; this is a special more-quickly implemented case of 4 below)
is "y" or "Y" (returns true)
is "n" or "N" (returns false)
does not explicitly exclude the sha1 hash of pkgAndName (see step 6)
is a suffix of the sha1 hash of pkgAndName (returns true)
OR if the (non-empty) value is in the regular language "(-[01]+/)+?([01]+(/[01]+)+?" (exclude..)(....include...) test the [01]+ exclude substrings, if any suffix-match, return false (4 above) test the [01]+ include substrings, if any suffix-match, return true The include substrings AFTER the first slash are numbered 0,1, etc and are named fmt.Sprintf("%s%d", varname, number) As an extra-special case for multiple failure search, an excludes-only string ending in a slash (terminated, not separated) implicitly specifies the include string "0/1", that is, match everything. (Exclude strings are used for automated search for multiple failures.) Clause 6 is not really intended for human use and only matters for failures that require multiple triggers.
Otherwise it returns false.
Unless Flags.Gossahash is empty, when DebugHashMatchPkgFunc returns true the message
"%s triggered %s\n", varname, pkgAndName
is printed on the file named in environment variable GSHS_LOGFILE, or standard out if that is empty. "Varname" is either the name of the variable or the name of the substring, depending on which matched.
Typical use:
you make a change to the compiler, say, adding a new phase
it is broken in some mystifying way, for example, make.bash builds a broken compiler that almost works, but crashes compiling a test in run.bash.
add this guard to the code, which by default leaves it broken, but does not run the broken new code if Flags.Gossahash is non-empty and non-matching:
if !base.DebugHashMatch(ir.PkgFuncName(fn)) { return nil // early exit, do nothing }
rebuild w/o the bad code, GOCOMPILEDEBUG=gossahash=n ./all.bash to verify that you put the guard in the right place with the right sense of the test.
use github.com/dr2chase/gossahash to search for the error:
go install github.com/dr2chase/gossahash@latest
gossahash -- <the thing that fails>
for example: GOMAXPROCS=1 gossahash -- ./all.bash
gossahash should return a single function whose miscompilation causes the problem, and you can focus on that.
func DebugHashMatchPos(pos src.XPos) bool
func ErrorExit()
ErrorExit handles an error-status exit. It flushes any pending errors, removes the output file, and exits.
func Errorf(format string, args ...interface{})
Errorf reports a formatted error at the current line.
func ErrorfAt(pos src.XPos, code errors.Code, format string, args ...interface{})
ErrorfAt reports a formatted error message at pos.
func Errors() int
Errors returns the number of errors reported.
func Exit(code int)
func ExitIfErrors()
ExitIfErrors calls ErrorExit if any errors have been reported.
func Fatalf(format string, args ...interface{})
Fatalf reports a fatal error - an internal problem - at the current line and exits. If other errors have already been printed, then Fatalf just quietly exits. (The internal problem may have been caused by incomplete information after the already-reported errors, so best to let users fix those and try again without being bothered about a spurious internal error.)
But if no errors have been printed, or if -d panic has been specified, Fatalf prints the error as an "internal compiler error". In a released build, it prints an error asking to file a bug report. In development builds, it prints a stack trace.
If -h has been specified, Fatalf panics to force the usual runtime info dump.
func FatalfAt(pos src.XPos, format string, args ...interface{})
FatalfAt reports a fatal error - an internal problem - at pos and exits. If other errors have already been printed, then FatalfAt just quietly exits. (The internal problem may have been caused by incomplete information after the already-reported errors, so best to let users fix those and try again without being bothered about a spurious internal error.)
But if no errors have been printed, or if -d panic has been specified, FatalfAt prints the error as an "internal compiler error". In a released build, it prints an error asking to file a bug report. In development builds, it prints a stack trace.
If -h has been specified, FatalfAt panics to force the usual runtime info dump.
func FlushErrors()
FlushErrors sorts errors seen so far by line number, prints them to stdout, and empties the errors array.
func FmtPos(pos src.XPos) string
FmtPos formats pos as a file:line string.
func HasDebugHash() bool
HasDebugHash returns true if Flags.Gossahash is non-empty, which results in hashDebug being not-nil. I.e., if !HasDebugHash(), there is no need to create the string for hashing and testing.
func Linkname(name string, abi obj.ABI) *obj.LSym
Linkname returns the linker symbol for the given name as it might appear within a //go:linkname directive.
func MapFile(f *os.File, offset, length int64) (string, error)
MapFile returns length bytes from the file starting at the specified offset as a string.
func ParseFlags()
ParseFlags parses the command-line flags into Flag.
func PkgLinksym(prefix, name string, abi obj.ABI) *obj.LSym
PkgLinksym returns the linker symbol for name within the given package prefix. For user packages, prefix should be the package path encoded with objabi.PathToPrefix.
func SyntaxErrors() int
SyntaxErrors returns the number of syntax errors reported.
func UpdateErrorDot(line string, name, expr string)
UpdateErrorDot is a clumsy hack that rewrites the last error, if it was "LINE: undefined: NAME", to be "LINE: undefined: NAME in EXPR". It is used to give better error messages for dot (selector) expressions.
func Warn(format string, args ...interface{})
Warn reports a formatted warning at the current line. In general the Go compiler does NOT generate warnings, so this should be used only when the user has opted in to additional output by setting a particular flag.
func WarnfAt(pos src.XPos, format string, args ...interface{})
WarnfAt reports a formatted warning at pos. In general the Go compiler does NOT generate warnings, so this should be used only when the user has opted in to additional output by setting a particular flag.
CmdFlags defines the command-line flags (see var Flag). Each struct field is a different flag, by default named for the lower-case of the field name. If the flag name is a single letter, the default flag name is left upper-case. If the flag name is "Lower" followed by a single letter, the default flag name is the lower-case of the last letter.
If this default flag name can't be made right, the `flag` struct tag can be used to replace it, but this should be done only in exceptional circumstances: it helps everyone if the flag name is obvious from the field name when the flag is used elsewhere in the compiler sources. The `flag:"-"` struct tag makes a field invisible to the flag logic and should also be used sparingly.
Each field must have a `help` struct tag giving the flag help message.
The allowed field types are bool, int, string, pointers to those (for values stored elsewhere), CountFlag (for a counting flag), and func(string) (for a flag that uses special code for parsing).
type CmdFlags struct { // Single letters B CountFlag "help:\"disable bounds checking\"" C CountFlag "help:\"disable printing of columns in error messages\"" D string "help:\"set relative `path` for local imports\"" E CountFlag "help:\"debug symbol export\"" I func(string) "help:\"add `directory` to import search path\"" K CountFlag "help:\"debug missing line numbers\"" L CountFlag "help:\"also show actual source file names in error messages for positions affected by //line directives\"" N CountFlag "help:\"disable optimizations\"" S CountFlag "help:\"print assembly listing\"" // V is added by objabi.AddVersionFlag W CountFlag "help:\"debug parse tree after type checking\"" LowerC int "help:\"concurrency during compilation (1 means no concurrency)\"" LowerD flag.Value "help:\"enable debugging settings; try -d help\"" LowerE CountFlag "help:\"no limit on number of errors reported\"" LowerH CountFlag "help:\"halt on error\"" LowerJ CountFlag "help:\"debug runtime-initialized variables\"" LowerL CountFlag "help:\"disable inlining\"" LowerM CountFlag "help:\"print optimization decisions\"" LowerO string "help:\"write output to `file`\"" LowerP *string "help:\"set expected package import `path`\"" // &Ctxt.Pkgpath, set below LowerR CountFlag "help:\"debug generated wrappers\"" LowerT bool "help:\"enable tracing for debugging the compiler\"" LowerW CountFlag "help:\"debug type checking\"" LowerV *bool "help:\"increase debug verbosity\"" // Special characters Percent CountFlag "flag:\"%\" help:\"debug non-static initializers\"" CompilingRuntime bool "flag:\"+\" help:\"compiling runtime\"" // Longer names AsmHdr string "help:\"write assembly header to `file`\"" ASan bool "help:\"build code compatible with C/C++ address sanitizer\"" Bench string "help:\"append benchmark times to `file`\"" BlockProfile string "help:\"write block profile to `file`\"" BuildID string "help:\"record `id` as the build id in the export metadata\"" CPUProfile string "help:\"write cpu profile to `file`\"" Complete bool "help:\"compiling complete package (no C or assembly)\"" ClobberDead bool "help:\"clobber dead stack slots (for debugging)\"" ClobberDeadReg bool "help:\"clobber dead registers (for debugging)\"" Dwarf bool "help:\"generate DWARF symbols\"" DwarfBASEntries *bool "help:\"use base address selection entries in DWARF\"" // &Ctxt.UseBASEntries, set below DwarfLocationLists *bool "help:\"add location lists to DWARF in optimized mode\"" // &Ctxt.Flag_locationlists, set below Dynlink *bool "help:\"support references to Go symbols defined in other shared libraries\"" // &Ctxt.Flag_dynlink, set below EmbedCfg func(string) "help:\"read go:embed configuration from `file`\"" Env func(string) "help:\"add `definition` of the form key=value to environment\"" GenDwarfInl int "help:\"generate DWARF inline info records\"" // 0=disabled, 1=funcs, 2=funcs+formals/locals GoVersion string "help:\"required version of the runtime\"" ImportCfg func(string) "help:\"read import configuration from `file`\"" InstallSuffix string "help:\"set pkg directory `suffix`\"" JSON string "help:\"version,file for JSON compiler/optimizer detail output\"" Lang string "help:\"Go language version source code expects\"" LinkObj string "help:\"write linker-specific object to `file`\"" LinkShared *bool "help:\"generate code that will be linked against Go shared libraries\"" // &Ctxt.Flag_linkshared, set below Live CountFlag "help:\"debug liveness analysis\"" MSan bool "help:\"build code compatible with C/C++ memory sanitizer\"" MemProfile string "help:\"write memory profile to `file`\"" MemProfileRate int "help:\"set runtime.MemProfileRate to `rate`\"" MutexProfile string "help:\"write mutex profile to `file`\"" NoLocalImports bool "help:\"reject local (relative) imports\"" CoverageCfg func(string) "help:\"read coverage configuration from `file`\"" Pack bool "help:\"write to file.a instead of file.o\"" Race bool "help:\"enable race detector\"" Shared *bool "help:\"generate code that can be linked into a shared library\"" // &Ctxt.Flag_shared, set below SmallFrames bool "help:\"reduce the size limit for stack allocated objects\"" // small stacks, to diagnose GC latency; see golang.org/issue/27732 Spectre string "help:\"enable spectre mitigations in `list` (all, index, ret)\"" Std bool "help:\"compiling standard library\"" SymABIs string "help:\"read symbol ABIs from `file`\"" TraceProfile string "help:\"write an execution trace to `file`\"" TrimPath string "help:\"remove `prefix` from recorded source file paths\"" WB bool "help:\"enable write barrier\"" // TODO: remove PgoProfile string "help:\"read profile or pre-process profile from `file`\"" ErrorURL bool "help:\"print explanatory URL with error message if applicable\"" // Configuration derived from flags; not a flag itself. Cfg struct { Embed struct { Patterns map[string][]string Files map[string]string } ImportDirs []string // appended to by -I ImportMap map[string]string // set by -importcfg PackageFile map[string]string // set by -importcfg; nil means not in use CoverageInfo *covcmd.CoverFixupConfig // set by -coveragecfg SpectreIndex bool // set by -spectre=index or -spectre=all // Whether we are adding any sort of code instrumentation, such as // when the race detector is enabled. Instrumenting bool } }
Flag holds the parsed command-line flags. See ParseFlag for non-zero defaults.
var Flag CmdFlags
A CountFlag is a counting integer flag. It accepts -name=value to set the value directly, but it also accepts -name with no =value to increment the count.
type CountFlag int
DebugFlags defines the debugging configuration values (see var Debug). Each struct field is a different value, named for the lower-case of the field name. Each field must be an int or string and must have a `help` struct tag.
The -d option takes a comma-separated list of settings. Each setting is name=value; for ints, name is short for name=1.
type DebugFlags struct { AlignHot int `help:"enable hot block alignment (currently requires -pgo)" concurrent:"ok"` Append int `help:"print information about append compilation"` Checkptr int `help:"instrument unsafe pointer conversions\n0: instrumentation disabled\n1: conversions involving unsafe.Pointer are instrumented\n2: conversions to unsafe.Pointer force heap allocation" concurrent:"ok"` Closure int `help:"print information about closure compilation"` Defer int `help:"print information about defer compilation"` DisableNil int `help:"disable nil checks" concurrent:"ok"` DumpInlFuncProps string `help:"dump function properties from inl heuristics to specified file"` DumpInlCallSiteScores int `help:"dump scored callsites during inlining"` InlScoreAdj string `help:"set inliner score adjustments (ex: -d=inlscoreadj=panicPathAdj:10/passConstToNestedIfAdj:-90)"` InlBudgetSlack int `help:"amount to expand the initial inline budget when new inliner enabled. Defaults to 80 if option not set." concurrent:"ok"` DumpPtrs int `help:"show Node pointers values in dump output"` DwarfInl int `help:"print information about DWARF inlined function creation"` EscapeMutationsCalls int `help:"print extra escape analysis diagnostics about mutations and calls" concurrent:"ok"` Export int `help:"print export data"` Fmahash string `help:"hash value for use in debugging platform-dependent multiply-add use" concurrent:"ok"` GCAdjust int `help:"log adjustments to GOGC" concurrent:"ok"` GCCheck int `help:"check heap/gc use by compiler" concurrent:"ok"` GCProg int `help:"print dump of GC programs"` Gossahash string `help:"hash value for use in debugging the compiler"` InlFuncsWithClosures int `help:"allow functions with closures to be inlined" concurrent:"ok"` InlStaticInit int `help:"allow static initialization of inlined calls" concurrent:"ok"` Libfuzzer int `help:"enable coverage instrumentation for libfuzzer"` LoopVar int `help:"shared (0, default), 1 (private loop variables), 2, private + log"` LoopVarHash string `help:"for debugging changes in loop behavior. Overrides experiment and loopvar flag."` LocationLists int `help:"print information about DWARF location list creation"` MaxShapeLen int `help:"hash shape names longer than this threshold (default 500)" concurrent:"ok"` MergeLocals int `help:"merge together non-interfering local stack slots" concurrent:"ok"` MergeLocalsDumpFunc string `help:"dump specified func in merge locals"` MergeLocalsHash string `help:"hash value for debugging stack slot merging of local variables" concurrent:"ok"` MergeLocalsTrace int `help:"trace debug output for locals merging"` MergeLocalsHTrace int `help:"hash-selected trace debug output for locals merging"` Nil int `help:"print information about nil checks"` NoOpenDefer int `help:"disable open-coded defers" concurrent:"ok"` NoRefName int `help:"do not include referenced symbol names in object file" concurrent:"ok"` PCTab string `help:"print named pc-value table\nOne of: pctospadj, pctofile, pctoline, pctoinline, pctopcdata"` Panic int `help:"show all compiler panics"` Reshape int `help:"print information about expression reshaping"` Shapify int `help:"print information about shaping recursive types"` Slice int `help:"print information about slice compilation"` SoftFloat int `help:"force compiler to emit soft-float code" concurrent:"ok"` StaticCopy int `help:"print information about missed static copies" concurrent:"ok"` SyncFrames int `help:"how many writer stack frames to include at sync points in unified export data"` TypeAssert int `help:"print information about type assertion inlining"` WB int `help:"print information about write barriers"` ABIWrap int `help:"print information about ABI wrapper generation"` MayMoreStack string `help:"call named function before all stack growth checks" concurrent:"ok"` PGODebug int `help:"debug profile-guided optimizations"` PGOHash string `help:"hash value for debugging profile-guided optimizations" concurrent:"ok"` PGOInline int `help:"enable profile-guided inlining" concurrent:"ok"` PGOInlineCDFThreshold string `help:"cumulative threshold percentage for determining call sites as hot candidates for inlining" concurrent:"ok"` PGOInlineBudget int `help:"inline budget for hot functions" concurrent:"ok"` PGODevirtualize int `help:"enable profile-guided devirtualization; 0 to disable, 1 to enable interface devirtualization, 2 to enable function devirtualization" concurrent:"ok"` RangeFuncCheck int `help:"insert code to check behavior of range iterator functions" concurrent:"ok"` WrapGlobalMapDbg int `help:"debug trace output for global map init wrapping"` WrapGlobalMapCtl int `help:"global map init wrap control (0 => default, 1 => off, 2 => stress mode, no size cutoff)"` ZeroCopy int `help:"enable zero-copy string->[]byte conversions" concurrent:"ok"` ConcurrentOk bool // true if only concurrentOk flags seen }
Debug holds the parsed debugging configuration values.
var Debug DebugFlags
type HashDebug struct {
// contains filtered or unexported fields
}
var FmaHash *HashDebug // for debugging fused-multiply-add floating point changes
var LoopVarHash *HashDebug // for debugging shared/private loop variable changes
var MergeLocalsHash *HashDebug // for debugging local stack slot merging changes
var PGOHash *HashDebug // for debugging PGO optimization decisions
func NewHashDebug(ev, s string, file io.Writer) *HashDebug
NewHashDebug returns a new hash-debug tester for the environment variable ev. If ev is not set, it returns nil, allowing a lightweight check for normal-case behavior.
func (d *HashDebug) MatchPkgFunc(pkg, fn string, note func() string) bool
MatchPkgFunc returns true if either the variable used to create d is unset, or if its value is y, or if it is a suffix of the base-two representation of the hash of pkg and fn. If the variable is not nil, then a true result is accompanied by stylized output to d.logfile, which is used for automated bug search.
func (d *HashDebug) MatchPos(pos src.XPos, desc func() string) bool
MatchPos is similar to MatchPkgFunc, but for hash computation it uses the source position including all inlining information instead of package name and path. Note that the default answer for no environment variable (d == nil) is "yes", do the thing.
func (d *HashDebug) MatchPosWithInfo(pos src.XPos, info any, desc func() string) bool
MatchPosWithInfo is similar to MatchPos, but with additional information that is included for hash computation, so it can distinguish multiple matches on the same source location. Note that the default answer for no environment variable (d == nil) is "yes", do the thing.
func (d *HashDebug) SetInlineSuffixOnly(b bool) *HashDebug
SetInlineSuffixOnly controls whether hashing and reporting use the entire inline position, or just the most-inline suffix. Compiler debugging tends to want the whole inlining, debugging user problems (loopvarhash, e.g.) typically does not need to see the entire inline tree, there is just one copy of the source code.
Timings collects the execution times of labeled phases which are added through a sequence of Start/Stop calls. Events may be associated with each phase via AddEvent.
type Timings struct {
// contains filtered or unexported fields
}
var Timer Timings
func (t *Timings) AddEvent(size int64, unit string)
AddEvent associates an event, i.e., a count, or an amount of data, with the most recently started or stopped phase; or the very first phase if Start or Stop hasn't been called yet. The unit specifies the unit of measurement (e.g., MB, lines, no. of funcs, etc.).
func (t *Timings) Start(labels ...string)
Start marks the beginning of a new phase and implicitly stops the previous phase. The phase name is the colon-separated concatenation of the labels.
func (t *Timings) Stop(labels ...string)
Stop marks the end of a phase and implicitly starts a new phase. The labels are added to the labels of the ended phase.
func (t *Timings) Write(w io.Writer, prefix string)
Write prints the phase times to w. The prefix is printed at the start of each line.