Compare commits

...

9 Commits

Author SHA1 Message Date
Zxilly e3c24e406c
Merge cefd445939 into 49cdf0c42e 2025-06-20 15:31:59 -04:00
Damien Neil 49cdf0c42e testing, testing/synctest: handle T.Helper in synctest bubbles
Fixes #74199

Change-Id: I6a15fbd59a3a3f8c496440f56d09d695e1504e4e
Reviewed-on: https://go-review.googlesource.com/c/go/+/682576
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
2025-06-20 12:29:58 -07:00
cuishuang 3bf1eecbd3 runtime: fix struct comment
Change-Id: I0c33830b13c8a187ac82504c7653abb8f8cf7530
Reviewed-on: https://go-review.googlesource.com/c/go/+/681655
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Sean Liao <sean@liao.dev>
2025-06-20 11:28:03 -07:00
Sean Liao 8ed23a2936 crypto/cipher: fix link to crypto/aes
Fixes #74309

Change-Id: I4d97514355d825124a8d879c2590b45b039f5fd1
Reviewed-on: https://go-review.googlesource.com/c/go/+/682596
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-06-20 11:09:26 -07:00
Adam Bender ef60769b46 go/doc: add a golden test that reproduces #62640
For #62640.
For #61394.

This is a copy of https://go-review.googlesource.com/c/go/+/528402,
which has stalled in review and the owner is no longer working on Go.

Change-Id: Ic7a1ae65c70d4857ab1061ccae1a926bf5c4ff55
Reviewed-on: https://go-review.googlesource.com/c/go/+/681235
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
2025-06-20 10:05:12 -07:00
Zxilly cefd445939
remove type:string 2025-06-06 04:18:02 +08:00
Zxilly a2c54efd5f
fix type name 2025-06-03 23:40:35 +08:00
Zxilly 182a289ef3
keep type name 2025-06-03 21:32:33 +08:00
Zxilly 900bf7e125
cmd: emit dwarf for string constants 2025-06-02 04:04:02 +08:00
14 changed files with 249 additions and 21 deletions

View File

@ -176,22 +176,34 @@ func dumpGlobalConst(n *ir.Name) {
return
}
// only export integer constants for now
if !t.IsInteger() {
if !t.IsInteger() && !t.IsString() {
return
}
v := n.Val()
if t.IsUntyped() {
// Export untyped integers as int (if they fit).
t = types.Types[types.TINT]
if ir.ConstOverflow(v, t) {
return
if t.IsInteger() {
// Export untyped integers as int (if they fit).
t = types.Types[types.TINT]
if ir.ConstOverflow(v, t) {
return
}
} else {
t = types.Types[types.TSTRING]
}
} else {
// If the type of the constant is an instantiated generic, we need to emit
// that type so the linker knows about it. See issue 51245.
_ = reflectdata.TypeLinksym(t)
if t.IsInteger() {
// If the type of the constant is an instantiated generic, we need to emit
// that type so the linker knows about it. See issue 51245.
_ = reflectdata.TypeLinksym(t)
}
// For const string, type:string isn't the real type.
}
if t.IsInteger() {
base.Ctxt.DwarfIntConst(n.Sym().Name, types.TypeSymName(t), ir.IntVal(t, v))
} else if t.IsString() {
base.Ctxt.DwarfStringConst(n.Sym().Name, types.TypeSymName(t), ir.StringVal(n))
}
base.Ctxt.DwarfIntConst(n.Sym().Name, types.TypeSymName(t), ir.IntVal(t, v))
}
// addGCLocals adds gcargs, gclocals, gcregs, and stack object symbols to Ctxt.Data.

View File

@ -27,6 +27,10 @@ const InfoPrefix = "go:info."
// entries that contain constants.
const ConstInfoPrefix = "go:constinfo."
// ConstStringInfoPrefix is the prefix for all symbols containing
// DWARF info entries that are referred by string constants.
const ConstStringInfoPrefix = "$const."
// CUInfoPrefix is the prefix for symbols containing information to
// populate the DWARF compilation unit info entries.
const CUInfoPrefix = "go:cuinfo."
@ -336,6 +340,7 @@ const (
DW_ABRV_INLINED_SUBROUTINE_RANGES
DW_ABRV_VARIABLE
DW_ABRV_INT_CONSTANT
DW_ABRV_STRING_CONSTANT
DW_ABRV_LEXICAL_BLOCK_RANGES
DW_ABRV_LEXICAL_BLOCK_SIMPLE
DW_ABRV_STRUCTFIELD
@ -354,6 +359,7 @@ const (
DW_ABRV_BARE_PTRTYPE // only for void*, no DW_AT_type attr to please gdb 6.
DW_ABRV_SLICETYPE
DW_ABRV_STRINGTYPE
DW_ABRV_CONSTANT_STRINGTYPE
DW_ABRV_STRUCTTYPE
DW_ABRV_TYPEDECL
DW_ABRV_DICT_INDEX
@ -575,7 +581,7 @@ var abbrevs = []dwAbbrev{
},
},
/* INT CONSTANT */
/* INT_CONSTANT */
{
DW_TAG_constant,
DW_CHILDREN_no,
@ -586,6 +592,17 @@ var abbrevs = []dwAbbrev{
},
},
/* STRING_CONSTANT */
{
DW_TAG_constant,
DW_CHILDREN_no,
[]dwAttrForm{
{DW_AT_name, DW_FORM_string},
{DW_AT_type, DW_FORM_ref_addr},
{DW_AT_const_value, DW_FORM_block1},
},
},
/* LEXICAL_BLOCK_RANGES */
{
DW_TAG_lexical_block,
@ -807,6 +824,16 @@ var abbrevs = []dwAbbrev{
},
},
/* CONSTANT_STRINGTYPE */
{
DW_TAG_string_type,
DW_CHILDREN_no,
[]dwAttrForm{
{DW_AT_name, DW_FORM_string},
{DW_AT_byte_size, DW_FORM_udata},
},
},
/* STRUCTTYPE */
{
DW_TAG_structure_type,
@ -1031,6 +1058,14 @@ func PutIntConst(ctxt Context, info, typ Sym, name string, val int64) {
putattr(ctxt, info, DW_ABRV_INT_CONSTANT, DW_FORM_sdata, DW_CLS_CONSTANT, val, nil)
}
// PutStringConst writes a DIE for a string constant
func PutStringConst(ctxt Context, info, typ Sym, name string, val string) {
Uleb128put(ctxt, info, DW_ABRV_STRING_CONSTANT)
putattr(ctxt, info, DW_ABRV_STRING_CONSTANT, DW_FORM_string, DW_CLS_STRING, int64(len(name)), name)
putattr(ctxt, info, DW_ABRV_STRING_CONSTANT, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, typ)
putattr(ctxt, info, DW_ABRV_STRING_CONSTANT, DW_FORM_block1, DW_CLS_BLOCK, int64(len(val)), []byte(val))
}
// PutGlobal writes a DIE for a global variable.
func PutGlobal(ctxt Context, info, typ, gvar Sym, name string) {
Uleb128put(ctxt, info, DW_ABRV_VARIABLE)

View File

@ -12,6 +12,7 @@ import (
"cmd/internal/src"
"fmt"
"slices"
"strconv"
"strings"
"sync"
)
@ -393,18 +394,38 @@ func (ctxt *Link) populateDWARF(curfn Func, s *LSym) {
ctxt.generateDebugLinesSymbol(s, lines)
}
// DwarfIntConst creates a link symbol for an integer constant with the
// given name, type and value.
func (ctxt *Link) DwarfIntConst(name, typename string, val int64) {
// ensureConstInfoSym ensures that the DWARF constant info symbol exists
func (ctxt *Link) ensureConstInfoSym() *LSym {
myimportpath := ctxt.Pkgpath
if myimportpath == "" {
return
return nil
}
s := ctxt.LookupInit(dwarf.ConstInfoPrefix+myimportpath, func(s *LSym) {
s.Type = objabi.SDWARFCONST
ctxt.Data = append(ctxt.Data, s)
})
dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), myimportpath+"."+name, val)
return s
}
// DwarfIntConst creates a link symbol for an integer constant with the
// given name, type and value.
func (ctxt *Link) DwarfIntConst(name, typename string, val int64) {
s := ctxt.ensureConstInfoSym()
if s == nil {
return
}
dwarf.PutIntConst(dwCtxt{ctxt}, s, ctxt.Lookup(dwarf.InfoPrefix+typename), ctxt.Pkgpath+"."+name, val)
}
// DwarfStringConst creates a link symbol for a string constant with the
// given name and value.
func (ctxt *Link) DwarfStringConst(name, typename, value string) {
s := ctxt.ensureConstInfoSym()
if s == nil {
return
}
typSym := ctxt.Lookup(dwarf.InfoPrefix + dwarf.ConstStringInfoPrefix + typename + "." + strconv.Itoa(len(value)))
dwarf.PutStringConst(dwCtxt{ctxt}, s, typSym, ctxt.Pkgpath+"."+name, value)
}
// DwarfGlobal creates a link symbol containing a DWARF entry for

View File

@ -29,6 +29,7 @@ import (
"path"
"runtime"
"slices"
"strconv"
"strings"
"sync"
)
@ -285,13 +286,16 @@ func (d *dwctxt) newdie(parent *dwarf.DWDie, abbrev int, name string) *dwarf.DWD
die.Link = parent.Child
parent.Child = die
newattr(die, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len(name)), name)
// Sanity check: all DIEs created in the linker should be named.
if name == "" {
panic("nameless DWARF DIE")
}
// for constant string types, we emit the nams later since it didn't use symbol name as DW_AT_name
if abbrev != dwarf.DW_ABRV_CONSTANT_STRINGTYPE {
newattr(die, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len(name)), name)
}
var st sym.SymKind
switch abbrev {
case dwarf.DW_ABRV_FUNCTYPEPARAM, dwarf.DW_ABRV_FUNCTYPEOUTPARAM, dwarf.DW_ABRV_DOTDOTDOT, dwarf.DW_ABRV_STRUCTFIELD, dwarf.DW_ABRV_ARRAYRANGE:
@ -1183,6 +1187,24 @@ func getCompilationDir() string {
return "."
}
func (d *dwctxt) genConstStringType(name string) {
if d.find(name) != 0 {
return
}
i := strings.LastIndex(name, ".")
if i < 0 {
log.Fatalf("error: invalid constant string type name %q", name)
}
size, err := strconv.ParseInt(name[i+1:], 10, 64)
if err != nil {
log.Fatalf("error: invalid constant string type name %q: %v", name, err)
}
atname := name[len(dwarf.ConstStringInfoPrefix):i]
die := d.newdie(&dwtypes, dwarf.DW_ABRV_CONSTANT_STRINGTYPE, name)
newattr(die, dwarf.DW_AT_name, dwarf.DW_CLS_STRING, int64(len(atname)), atname)
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, size, 0)
}
func (d *dwctxt) importInfoSymbol(dsym loader.Sym) {
d.ldr.SetAttrReachable(dsym, true)
d.ldr.SetAttrNotInSymbolTable(dsym, true)
@ -1207,6 +1229,15 @@ func (d *dwctxt) importInfoSymbol(dsym loader.Sym) {
// symbol name here?
sn := d.ldr.SymName(rsym)
tn := sn[len(dwarf.InfoPrefix):]
// If the symbol is a constant string type, we generate it
// These types do not exist in go,
// but can tell gdb how to interpret the corresponding values
if strings.HasPrefix(tn, dwarf.ConstStringInfoPrefix) {
d.genConstStringType(tn)
continue
}
ts := d.ldr.Lookup("type:"+tn, 0)
d.defgotype(ts)
}

View File

@ -82,7 +82,7 @@ func newGCM(cipher Block, nonceSize, tagSize int) (AEAD, error) {
// NewGCMWithRandomNonce returns the given cipher wrapped in Galois Counter
// Mode, with randomly-generated nonces. The cipher must have been created by
// [aes.NewCipher].
// [crypto/aes.NewCipher].
//
// It generates a random 96-bit nonce, which is prepended to the ciphertext by Seal,
// and is extracted from the ciphertext by Open. The NonceSize of the AEAD is zero,

22
src/go/doc/testdata/issue62640.0.golden vendored Normal file
View File

@ -0,0 +1,22 @@
//
PACKAGE issue62640
IMPORTPATH
testdata/issue62640
FILENAMES
testdata/issue62640.go
TYPES
//
type E struct{}
// F should be hidden within S because of the S.F field.
func (E) F()
//
type S struct {
E
F int
}

22
src/go/doc/testdata/issue62640.1.golden vendored Normal file
View File

@ -0,0 +1,22 @@
//
PACKAGE issue62640
IMPORTPATH
testdata/issue62640
FILENAMES
testdata/issue62640.go
TYPES
//
type E struct{}
// F should be hidden within S because of the S.F field.
func (E) F()
//
type S struct {
E
F int
}

25
src/go/doc/testdata/issue62640.2.golden vendored Normal file
View File

@ -0,0 +1,25 @@
//
PACKAGE issue62640
IMPORTPATH
testdata/issue62640
FILENAMES
testdata/issue62640.go
TYPES
//
type E struct{}
// F should be hidden within S because of the S.F field.
func (E) F()
//
type S struct {
E
F int
}
// F should be hidden within S because of the S.F field.
func (S) F()

15
src/go/doc/testdata/issue62640.go vendored Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package issue62640
type E struct{}
// F should be hidden within S because of the S.F field.
func (E) F() {}
type S struct {
E
F int
}

View File

@ -312,8 +312,10 @@ type heapArena struct {
// during marking.
pageSpecials [pagesPerArena / 8]uint8
// pageUseSpanDartboard is a bitmap that indicates which spans are
// heap spans and also gcUsesSpanDartboard.
// pageUseSpanInlineMarkBits is a bitmap where each bit corresponds
// to a span, as only spans one page in size can have inline mark bits.
// The bit indicates that the span has a spanInlineMarkBits struct
// stored directly at the top end of the span's memory.
pageUseSpanInlineMarkBits [pagesPerArena / 8]uint8
// checkmarks stores the debug.gccheckmark state. It is only

View File

@ -662,6 +662,9 @@ package main
const aConstant int = 42
const largeConstant uint64 = ^uint64(0)
const minusOne int64 = -1
const typedS string = "typed string"
const untypedS = "untyped string"
const nulS string = "\x00str"
func main() {
println("hello world")
@ -700,6 +703,9 @@ func TestGdbConst(t *testing.T) {
"-ex", "print main.minusOne",
"-ex", "print 'runtime.mSpanInUse'",
"-ex", "print 'runtime._PageSize'",
"-ex", "print main.typedS",
"-ex", "print main.untypedS",
"-ex", "print main.nulS",
filepath.Join(dir, "a.exe"),
}
gdbArgsFixup(args)
@ -711,7 +717,14 @@ func TestGdbConst(t *testing.T) {
sgot := strings.ReplaceAll(string(got), "\r\n", "\n")
if !strings.Contains(sgot, "\n$1 = 42\n$2 = 18446744073709551615\n$3 = -1\n$4 = 1 '\\001'\n$5 = 8192") {
if !strings.Contains(sgot, `$1 = 42
$2 = 18446744073709551615
$3 = -1
$4 = 1 '\001'
$5 = 8192
$6 = "typed string"
$7 = "untyped string"
$8 = "\000str"`) {
t.Fatalf("output mismatch")
}
}

View File

@ -0,0 +1,15 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package synctest_test
import "testing"
// helperLog is a t.Helper which logs.
// Since it is a helper, the log prefix should contain
// the caller's file, not helper_test.go.
func helperLog(t *testing.T, s string) {
t.Helper()
t.Log(s)
}

View File

@ -140,6 +140,18 @@ func TestRun(t *testing.T) {
})
}
func TestHelper(t *testing.T) {
runTest(t, []string{"-test.v"}, func() {
synctest.Test(t, func(t *testing.T) {
helperLog(t, "log in helper")
})
}, `^=== RUN TestHelper
synctest_test.go:.* log in helper
--- PASS: TestHelper.*
PASS
$`)
}
func wantPanic(t *testing.T, want string) {
if e := recover(); e != nil {
if got := fmt.Sprint(e); got != want {

View File

@ -1261,6 +1261,9 @@ func (c *common) Skipped() bool {
// When printing file and line information, that function will be skipped.
// Helper may be called simultaneously from multiple goroutines.
func (c *common) Helper() {
if c.isSynctest {
c = c.parent
}
c.mu.Lock()
defer c.mu.Unlock()
if c.helperPCs == nil {