Repository: go-delve/delve
Pull request #3032 (2022-06-14 07:59:04)

dwarf/frame: discard indirect flag reading personality func in eh_frame
We don't do anything with the personality function so there is no point
in complaining that we don't fully support the pointer encoding flags
used to describe it.

This matches the current level of support of pointer encodings in gdb
(they are discarded when reading the personality function and not
supported for FDEs because gcc doesn't generate them).

Fixes #3015



Patch:
diff --git a/pkg/dwarf/frame/entries.go b/pkg/dwarf/frame/entries.go
index 4c6f94d0..1e4605ce 100644
--- a/pkg/dwarf/frame/entries.go
+++ b/pkg/dwarf/frame/entries.go
@@ -108,8 +108,8 @@ func (fdes FrameDescriptionEntries) Append(otherFDEs FrameDescriptionEntries) Fr
 // ptrEnc represents a pointer encoding value, used during eh_frame decoding
 // to determine how pointers were encoded.
 // Least significant 4 (0xf) bytes encode the size  as well as its
-// signed-ness,  most significant 4 bytes (0xf0) are flags describing how
-// the value should be interpreted (absolute, relative...)
+// signed-ness,  most significant 4 bytes (0xf0 == ptrEncFlagsMask) are flags
+// describing how the value should be interpreted (absolute, relative...)
 // See https://www.airs.com/blog/archives/460.
 type ptrEnc uint8
 
@@ -126,12 +126,16 @@ const (
 	ptrEncSdata4 ptrEnc = 0x0b // 4 bytes, signed
 	ptrEncSdata8 ptrEnc = 0x0c // 8 bytes, signed
 
+	ptrEncFlagsMask ptrEnc = 0xf0
+
 	ptrEncPCRel    ptrEnc = 0x10 // value is relative to the memory address where it appears
 	ptrEncTextRel  ptrEnc = 0x20 // value is relative to the address of the text section
 	ptrEncDataRel  ptrEnc = 0x30 // value is relative to the address of the data section
 	ptrEncFuncRel  ptrEnc = 0x40 // value is relative to the start of the function
 	ptrEncAligned  ptrEnc = 0x50 // value should be aligned
 	ptrEncIndirect ptrEnc = 0x80 // value is an address where the real value of the pointer is stored
+
+	ptrEncSupportedFlags = ptrEncPCRel
 )
 
 // Supported returns true if this pointer encoding is supported.
@@ -142,7 +146,7 @@ func (ptrEnc ptrEnc) Supported() bool {
 			// These values aren't defined at the moment
 			return false
 		}
-		if ptrEnc&0xf0 != ptrEncPCRel {
+		if (ptrEnc&ptrEncFlagsMask)&^ptrEncSupportedFlags != 0 {
 			// Currently only the PC relative flag is supported
 			return false
 		}
diff --git a/pkg/dwarf/frame/parser.go b/pkg/dwarf/frame/parser.go
index bcec7e56..147ca34f 100644
--- a/pkg/dwarf/frame/parser.go
+++ b/pkg/dwarf/frame/parser.go
@@ -201,12 +201,13 @@ func parseCIE(ctx *parseContext) parsefunc {
 				// the pointer to the personality function encoded as specified by the
 				// pointer encoding.
 				// We don't support this but have to read it anyway.
-				e, _ := buf.ReadByte()
-				if !ptrEnc(e).Supported() {
+				b, _ := buf.ReadByte()
+				e := ptrEnc(b) &^ ptrEncIndirect
+				if !e.Supported() {
 					ctx.err = fmt.Errorf("pointer encoding not supported %#x at %#x", e, ctx.offset())
 					return nil
 				}
-				ctx.readEncodedPtr(0, buf, ptrEnc(e))
+				ctx.readEncodedPtr(0, buf, e)
 			default:
 				ctx.err = fmt.Errorf("unsupported augmentation character %c at %#x", ctx.common.Augmentation[i], ctx.offset())
 				return nil
diff --git a/pkg/proc/eval.go b/pkg/proc/eval.go
index 24c5a6bd..61109352 100644
--- a/pkg/proc/eval.go
+++ b/pkg/proc/eval.go
@@ -2038,10 +2038,18 @@ func (v *Variable) mapAccess(idx *Variable) (*Variable, error) {
 		return nil, fmt.Errorf("can not access unreadable map: %v", v.Unreadable)
 	}
 
+	lcfg := loadFullValue
+	if idx.Kind == reflect.String && int64(len(constant.StringVal(idx.Value))) == idx.Len && idx.Len > int64(lcfg.MaxStringLen) {
+		// If the index is a string load as much of the keys to at least match the length of the index.
+		//TODO(aarzilli): when struct literals are implemented this needs to be
+		//done recursively for literal struct fields.
+		lcfg.MaxStringLen = int(idx.Len)
+	}
+
 	first := true
 	for it.next() {
 		key := it.key()
-		key.loadValue(loadFullValue)
+		key.loadValue(lcfg)
 		if key.Unreadable != nil {
 			return nil, fmt.Errorf("can not access unreadable map: %v", key.Unreadable)
 		}
diff --git a/pkg/proc/native/proc_windows.go b/pkg/proc/native/proc_windows.go
index e9e94b5c..38863fef 100644
--- a/pkg/proc/native/proc_windows.go
+++ b/pkg/proc/native/proc_windows.go
@@ -38,6 +38,11 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ strin
 		return nil, err
 	}
 
+	creationFlags := uint32(_DEBUG_ONLY_THIS_PROCESS)
+	if flags&proc.LaunchForeground == 0 {
+		creationFlags |= syscall.CREATE_NEW_PROCESS_GROUP
+	}
+
 	var p *os.Process
 	dbp := newProcess(0)
 	dbp.execPtraceFunc(func() {
@@ -45,7 +50,7 @@ func Launch(cmd []string, wd string, flags proc.LaunchFlags, _ []string, _ strin
 			Dir:   wd,
 			Files: []*os.File{stdin, stdout, stderr},
 			Sys: &syscall.SysProcAttr{
-				CreationFlags: _DEBUG_ONLY_THIS_PROCESS,
+				CreationFlags: creationFlags,
 			},
 			Env: env,
 		}


Test patch:
diff --git a/pkg/proc/variables_test.go b/pkg/proc/variables_test.go
index 13c4c445..145364e8 100644
--- a/pkg/proc/variables_test.go
+++ b/pkg/proc/variables_test.go
@@ -794,6 +794,9 @@ func TestEvalExpression(t *testing.T) {
 		// pretty printing special types
 		{"tim1", false, `time.Time(1977-05-25T18:00:00Z)…`, `time.Time(1977-05-25T18:00:00Z)…`, "time.Time", nil},
 		{"tim2", false, `time.Time(2022-06-07T02:03:04-06:00)…`, `time.Time(2022-06-07T02:03:04-06:00)…`, "time.Time", nil},
+
+		// issue #3034 - map access with long string key
+		{`m6["very long string 0123456789a0123456789b0123456789c0123456789d0123456789e0123456789f0123456789g012345678h90123456789i0123456789j0123456789"]`, false, `123`, `123`, "int", nil},
 	}
 
 	ver, _ := goversion.Parse(runtime.Version())