github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/mm/debug.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package mm 16 17 import ( 18 "bytes" 19 "fmt" 20 21 "github.com/SagerNet/gvisor/pkg/context" 22 ) 23 24 const ( 25 // If checkInvariants is true, perform runtime checks for invariants 26 // expected by the mm package. This is normally disabled since MM is a 27 // significant hot path in general, and some such checks (notably 28 // memmap.CheckTranslateResult) are very expensive. 29 checkInvariants = false 30 31 // If logIOErrors is true, log I/O errors that originate from MM before 32 // converting them to EFAULT. 33 logIOErrors = false 34 ) 35 36 // String implements fmt.Stringer.String. 37 func (mm *MemoryManager) String() string { 38 return mm.DebugString(context.Background()) 39 } 40 41 // DebugString returns a string containing information about mm for debugging. 42 func (mm *MemoryManager) DebugString(ctx context.Context) string { 43 mm.mappingMu.RLock() 44 defer mm.mappingMu.RUnlock() 45 mm.activeMu.RLock() 46 defer mm.activeMu.RUnlock() 47 return mm.debugStringLocked(ctx) 48 } 49 50 // Preconditions: mm.mappingMu and mm.activeMu must be locked. 51 func (mm *MemoryManager) debugStringLocked(ctx context.Context) string { 52 var b bytes.Buffer 53 b.WriteString("VMAs:\n") 54 for vseg := mm.vmas.FirstSegment(); vseg.Ok(); vseg = vseg.NextSegment() { 55 b.Write(mm.vmaMapsEntryLocked(ctx, vseg)) 56 } 57 b.WriteString("PMAs:\n") 58 for pseg := mm.pmas.FirstSegment(); pseg.Ok(); pseg = pseg.NextSegment() { 59 b.Write(pseg.debugStringEntryLocked()) 60 } 61 return string(b.Bytes()) 62 } 63 64 // Preconditions: mm.activeMu must be locked. 65 func (pseg pmaIterator) debugStringEntryLocked() []byte { 66 var b bytes.Buffer 67 68 fmt.Fprintf(&b, "%08x-%08x ", pseg.Start(), pseg.End()) 69 70 pma := pseg.ValuePtr() 71 if pma.effectivePerms.Read { 72 b.WriteByte('r') 73 } else { 74 b.WriteByte('-') 75 } 76 if pma.effectivePerms.Write { 77 if pma.needCOW { 78 b.WriteByte('c') 79 } else { 80 b.WriteByte('w') 81 } 82 } else { 83 b.WriteByte('-') 84 } 85 if pma.effectivePerms.Execute { 86 b.WriteByte('x') 87 } else { 88 b.WriteByte('-') 89 } 90 if pma.private { 91 b.WriteByte('p') 92 } else { 93 b.WriteByte('s') 94 } 95 96 fmt.Fprintf(&b, " %08x %T\n", pma.off, pma.file) 97 return b.Bytes() 98 }