x/debug: handle page size differences
The page size of the core dump writer and reader may differ.
Handle that fact.
Change-Id: I81bb7fc946c1aed6f8df71056aae24668a7293de
Reviewed-on: https://go-review.googlesource.com/88156
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Peter Weinberger <pjw@google.com>
diff --git a/core/process.go b/core/process.go
index 8254092..5a25ad4 100644
--- a/core/process.go
+++ b/core/process.go
@@ -152,7 +152,9 @@
}
// Memory map all the mappings.
+ hostPageSize := int64(syscall.Getpagesize())
for _, m := range p.mappings {
+ size := m.max.Sub(m.min)
if m.f == nil {
// We don't have any source for this data.
// Could be a mapped file that we couldn't find.
@@ -166,18 +168,33 @@
// TODO: this allocation could be large.
// Use mmap to avoid real backing store for all those zeros, or
// perhaps split the mapping up into chunks and share the zero contents among them.
- m.contents = make([]byte, m.max.Sub(m.min))
+ m.contents = make([]byte, size)
continue
}
if m.perm&Write != 0 && m.f != core {
p.warnings = append(p.warnings,
fmt.Sprintf("Writeable data at [%x %x] missing from core. Using possibly stale backup source %s.", m.min, m.max, m.f.Name()))
}
- var err error
- m.contents, err = syscall.Mmap(int(m.f.Fd()), m.off, int(m.max.Sub(m.min)), syscall.PROT_READ, syscall.MAP_SHARED)
- if err != nil {
- return nil, fmt.Errorf("can't memory map %s at %d: %s\n", m.f.Name(), m.off, err)
+ // Data in core file might not be aligned enough for the host.
+ // Expand memory range so we can map full pages.
+ minOff := m.off
+ maxOff := m.off + size
+ minOff -= minOff % hostPageSize
+ if maxOff%hostPageSize != 0 {
+ maxOff += hostPageSize - maxOff%hostPageSize
}
+
+ // Read data from file.
+ data, err := syscall.Mmap(int(m.f.Fd()), minOff, int(maxOff-minOff), syscall.PROT_READ, syscall.MAP_SHARED)
+ if err != nil {
+ return nil, fmt.Errorf("can't memory map %s at %x: %s\n", m.f.Name(), minOff, err)
+ }
+
+ // Trim any data we mapped but don't need.
+ data = data[m.off-minOff:]
+ data = data[:size]
+
+ m.contents = data
}
// Build page table for mapping lookup.