{"record":{"id":"34c0bbbfca460db4","repo":"go-delve/delve","slug":"examine-memory-error-w","errorCode":null,"errorMessage":"examine memory error: %w","messagePattern":"examine memory error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/dap/command.go","lineNumber":201,"sourceCode":"\t\t\taddress = uint64(n)\n\t\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: // \"-x 0xc000079f20 + 8\" or -x 824634220320 + 8\n\t\t\taddress, _ = constant.Uint64Val(val.Value)\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unsupported expression type: %s\", val.Kind).Error(), nil\n\t\t}\n\t} else {\n\t\taddress, err = strconv.ParseUint(args.Operand, 0, 64)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"convert address into uintptr type failed, %s\", err).Error(), nil\n\t\t}\n\t}\n\n\tmemory, err := s.debugger.ExamineMemory(\n\t\taddress,\n\t\tmin(int(args.Count*args.Size), rpc2.ExamineMemoryLengthLimit),\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"examine memory error: %w\", err).Error(), nil\n\t}\n\n\treturn api.PrettyExamineMemory(uintptr(address), memory, true, args.Format, int(args.Size)), nil\n}\n\nfunc (s *Session) evaluateConfig(_, _ int, expr string) (string, error) {\n\targv := config.Split2PartsBySpace(expr)\n\tname := argv[0]\n\tif name == \"-list\" {\n\t\tif len(argv) > 1 {\n\t\t\treturn config.ConfigureListByName(&s.args, argv[1], \"cfgName\"), nil\n\t\t}\n\t\treturn listConfig(&s.args), nil\n\t}\n\tupdated, res, err := configureSet(&s.args, expr)\n\tif err != nil {\n\t\treturn \"\", err\n\t}","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/dap/command.go#L183-L219","documentation":"After the address is resolved, DAP's examineMemory delegates to debugger.ExamineMemory to read target process memory. Any failure from that read (unmapped page, exited process, invalid address, truncated count) is wrapped as 'examine memory error: %w'. The wrapped inner error carries the actual cause.","triggerScenarios":"Calling examine-memory with an address that is not mapped in the debuggee, reading after the target has exited or is not stopped, requesting Count*Size bytes spanning an unmapped region, or a backend memory-read failure (ptrace/gdbserial/core error).","commonSituations":"Reading a stale address after the program re-ran or reallocated; typo in a hand-copied address; examining memory in a core dump or remote session where the page is not present; debugging a process that was killed between steps.","solutions":["Read the wrapped cause (%w) to identify whether the address is unmapped, the process exited, or the read was too large.","Re-derive the address from a live expression with 'examine-memory -x &var' instead of reusing a stale literal address.","Reduce the count/size so the read stays within the mapped region (and under rpc2.ExamineMemoryLengthLimit).","Ensure the target is alive and stopped at a breakpoint before examining memory."],"exampleFix":"// before: reusing stale address\nexamine-memory 0xc000014000\n// after: evaluate the live pointer\nexamine-memory -x &myStruct","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if out, err := doExamineMemory(addr, count); err != nil {\n    var cause string\n    if unwrapped := errors.Unwrap(err); unwrapped != nil {\n        cause = unwrapped.Error() // distinguish unmapped vs exited process\n    }\n    log.Printf(\"examine-memory failed: %v (cause: %s)\", err, cause)\n}","preventionTips":["Re-evaluate pointers with -x instead of caching literal addresses across steps","Keep reads small and within one mapped region","Ensure the target is stopped and alive before reading memory"],"tags":["dap","memory-inspection","process-memory"],"backgroundTag":"memory-read-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}