diff --git a/process/coredump.go b/process/coredump.go index c57e0fcf0..8665b63e9 100644 --- a/process/coredump.go +++ b/process/coredump.go @@ -23,30 +23,30 @@ import ( ) const ( - // maxNotesSection the maximum section size for notes + // maxNotesSection is the maximum section size for notes. maxNotesSection = 16 * 1024 * 1024 ) -// CoredumpProcess implements Process interface to ELF coredumps +// CoredumpProcess implements Process interface to ELF coredumps. type CoredumpProcess struct { *pfelf.File - // files contains coredump's files by name + // files contains coredump's files by name. files map[string]*CoredumpFile - // pid the original PID of the coredump + // pid is the original PID from which the coredump was generated. pid libpf.PID - // machineData contains the parsed machine data + // machineData contains the parsed machine data. machineData MachineData - // mappings contains the parsed mappings + // mappings contains the parsed mappings. mappings []Mapping - // threadInfo contains the parsed thread info + // threadInfo contains the parsed thread info. threadInfo []ThreadInfo - // execPhdrPtr points to the main executable's program headers + // execPhdrPtr points to the main executable's program headers. execPhdrPtr libpf.Address // hasMusl is set if musl c-library is detected in this coredump. This @@ -57,27 +57,27 @@ type CoredumpProcess struct { var _ Process = &CoredumpProcess{} -// CoredumpMapping describes a file backed mapping in a coredump +// CoredumpMapping describes a file backed mapping in a coredump. type CoredumpMapping struct { - // Corresponding PT_LOAD segment + // Prog points to the corresponding PT_LOAD segment. Prog *pfelf.Prog - // File is the backing file for this mapping + // File is the backing file for this mapping. File *CoredumpFile - // FileOffset is the offset in the original backing file + // FileOffset is the offset in the original backing file. FileOffset uint64 } -// CoredumpFile contains information about a file mapped into a coredump +// CoredumpFile contains information about a file mapped into a coredump. type CoredumpFile struct { - // parent is the Coredump inside which this file is + // parent is the Coredump inside which this file is. parent *CoredumpProcess - // inode is the synthesized inode for this file + // inode is the synthesized inode for this file. inode uint64 - // Name is the mapped file's name + // Name is the mapped file's name. Name string - // Mappings contains mappings regarding this file + // Mappings contains mappings regarding this file. Mappings []CoredumpMapping - // Base is the virtual address where this file is loaded + // Base is the virtual address where this file is loaded. Base uint64 } @@ -127,10 +127,10 @@ func OpenCoredump(name string) (*CoredumpProcess, error) { // It's the value of a map indexed with mapping virtual address, and contains the data // needed to associate data from different coredump data structures to proper internals. type vaddrMappings struct { - // prog is the ELF PT_LOAD Program header for this virtual address + // prog is the ELF PT_LOAD Program header for this virtual address. prog *pfelf.Prog - // mappingIndex is the mapping's index in processState.Mappings + // mappingIndex is the mapping's index in processState.Mappings. mappingIndex int } @@ -194,7 +194,7 @@ func OpenCoredumpFile(f *pfelf.File) (*CoredumpProcess, error) { break } - // Parse the note if we are interested in it (skip others) + // Parse the note if we are interested in it (skip others). name := string(nameBytes) ty := elf.NType(note.Type) if name == NAMESPACE_CORE { @@ -247,38 +247,38 @@ func (cd *CoredumpProcess) MainExecutable() string { return "" } -// PID implements the Process interface +// PID implements the Process interface. func (cd *CoredumpProcess) PID() libpf.PID { return cd.pid } -// GetMachineData implements the Process interface +// GetMachineData implements the Process interface. func (cd *CoredumpProcess) GetMachineData() MachineData { return cd.machineData } -// GetMappings implements the Process interface +// GetMappings implements the Process interface. func (cd *CoredumpProcess) GetMappings() ([]Mapping, uint32, error) { return cd.mappings, 0, nil } -// GetThreadInfo implements the Process interface +// GetThreadInfo implements the Process interface. func (cd *CoredumpProcess) GetThreads() ([]ThreadInfo, error) { return cd.threadInfo, nil } -// OpenMappingFile implements the Process interface +// OpenMappingFile implements the Process interface. func (cd *CoredumpProcess) OpenMappingFile(_ *Mapping) (ReadAtCloser, error) { - // No filesystem level backing file in coredumps + // Coredumps do not contain the original backing files. return nil, errors.New("coredump does not support opening backing file") } -// GetMappingFileLastModified implements the Process interface +// GetMappingFileLastModified implements the Process interface. func (cd *CoredumpProcess) GetMappingFileLastModified(_ *Mapping) int64 { return 0 } -// CalculateMappingFileID implements the Process interface +// CalculateMappingFileID implements the Process interface. func (cd *CoredumpProcess) CalculateMappingFileID(m *Mapping) (libpf.FileID, error) { // It is not possible to calculate the real FileID as the section headers // are likely missing. So just return a synthesized FileID. @@ -291,7 +291,7 @@ func (cd *CoredumpProcess) CalculateMappingFileID(m *Mapping) (libpf.FileID, err return libpf.FileIDFromBytes(h.Sum(nil)) } -// OpenELF implements the ELFOpener and Process interfaces +// OpenELF implements the ELFOpener and Process interfaces. func (cd *CoredumpProcess) OpenELF(path string) (*pfelf.File, error) { // Fallback to directly returning the data from coredump. This comes with caveats: // @@ -312,13 +312,13 @@ func (cd *CoredumpProcess) OpenELF(path string) (*pfelf.File, error) { return nil, fmt.Errorf("ELF file `%s` not found", path) } -// ExtractAsFile implements the Process interface +// ExtractAsFile implements the Process interface. func (cd *CoredumpProcess) ExtractAsFile(_ string) (string, error) { - // No filesystem level backing file in coredumps + // Coredumps do not contain the original backing files. return "", errors.New("coredump does not support opening backing file") } -// getFile returns (creating if needed) a matching CoredumpFile for given file name +// getFile returns (creating if needed) a matching CoredumpFile for given file name. func (cd *CoredumpProcess) getFile(name string) *CoredumpFile { if cf, ok := cd.files[name]; ok { return cf @@ -335,18 +335,18 @@ func (cd *CoredumpProcess) getFile(name string) *CoredumpFile { return cf } -// FileMappingHeader64 is the header for CORE/NT_FILE note +// FileMappingHeader64 is the header for CORE/NT_FILE note. type FileMappingHeader64 struct { Entries uint64 PageSize uint64 } -// FileMappingEntry64 is the per-mapping data header in CORE/NT_FILE note +// FileMappingEntry64 is the per-mapping data header in CORE/NT_FILE note. type FileMappingEntry64 struct { Start, End, FileOffset uint64 } -// parseMappings processes CORE/NT_FILE note with description of memory mappings +// parseMappings processes a CORE/NT_FILE note with the description of memory mappings. func (cd *CoredumpProcess) parseMappings(desc []byte, vaddrToMappings map[uint64]vaddrMappings) error { hdrSize := uint64(unsafe.Sizeof(FileMappingHeader64{})) @@ -392,7 +392,7 @@ func (cd *CoredumpProcess) parseMappings(desc []byte, mapping := &cd.mappings[m.mappingIndex] mapping.Path = cf.Name mapping.FileOffset = entry.FileOffset * hdr.PageSize - // Synthesize non-zero device and inode indicating this is a filebacked mapping + // Synthesize non-zero device and inode indicating this is a filebacked mapping. mapping.Device = 1 mapping.Inode = cf.inode } @@ -401,7 +401,7 @@ func (cd *CoredumpProcess) parseMappings(desc []byte, return nil } -// parseAuxVector processes CORE/NT_AUXV note +// parseAuxVector processes a CORE/NT_AUXV note. func (cd *CoredumpProcess) parseAuxVector(desc []byte, vaddrToMappings map[uint64]vaddrMappings) { for i := 0; i+16 <= len(desc); i += 16 { value := binary.LittleEndian.Uint64(desc[i+8:]) @@ -429,7 +429,7 @@ func (cd *CoredumpProcess) parseAuxVector(desc []byte, vaddrToMappings map[uint6 } } -// PrpsInfo64 is the 64-bit NT_PRPSINFO note header +// PrpsInfo64 is the 64-bit NT_PRPSINFO note header. type PrpsInfo64 struct { State uint8 Sname uint8 @@ -447,7 +447,7 @@ type PrpsInfo64 struct { Args [80]byte } -// parseProcessInfo processes CORE/NT_PRPSINFO note +// parseProcessInfo processes a CORE/NT_PRPSINFO note. func (cd *CoredumpProcess) parseProcessInfo(desc []byte) error { if len(desc) == int(unsafe.Sizeof(PrpsInfo64{})) { info := (*PrpsInfo64)(unsafe.Pointer(&desc[0])) @@ -457,7 +457,7 @@ func (cd *CoredumpProcess) parseProcessInfo(desc []byte) error { return fmt.Errorf("unsupported NT_PRPSINFO size: %d", len(desc)) } -// parseProcessStatus processes CORE/NT_PRSTATUS note +// parseProcessStatus processes a CORE/NT_PRSTATUS note. func (cd *CoredumpProcess) parseProcessStatus(desc []byte) error { // The corresponding struct definition can be found here: // https://github.com/torvalds/linux/blob/49d766f3a0e4/include/linux/elfcore.h#L48 diff --git a/process/types.go b/process/types.go index a2126a6b5..7ca146b72 100644 --- a/process/types.go +++ b/process/types.go @@ -16,27 +16,27 @@ import ( "go.opentelemetry.io/ebpf-profiler/util" ) -// VdsoPathName is the path to use for VDSO mappings +// VdsoPathName is the path to use for VDSO mappings. const VdsoPathName = "linux-vdso.1.so" -// vdsoInode is the synthesized inode number for VDSO mappings +// vdsoInode is the synthesized inode number for VDSO mappings. const vdsoInode = 50 -// Mapping contains information about a memory mapping +// Mapping contains information about a memory mapping. type Mapping struct { - // Vaddr is the virtual memory start for this mapping + // Vaddr is the virtual memory start for this mapping. Vaddr uint64 - // Length is the length of the mapping + // Length is the length of the mapping. Length uint64 - // Flags contains the mapping flags and permissions + // Flags contains the mapping flags and permissions. Flags elf.ProgFlag - // FileOffset contains for file backed mappings the offset from the file start + // FileOffset contains for file backed mappings the offset from the file start. FileOffset uint64 - // Device holds the device ID where the file is located + // Device holds the device ID where the file is located. Device uint64 - // Inode holds the mapped file's inode number + // Inode holds the mapped file's inode number. Inode uint64 - // Path contains the file name for file backed mappings + // Path contains the file name for file backed mappings. Path string } @@ -63,19 +63,19 @@ func (m *Mapping) GetOnDiskFileIdentifier() util.OnDiskFileIdentifier { } } -// ThreadInfo contains the information about a thread CPU state needed for unwinding +// ThreadInfo contains the information about a thread CPU state needed for unwinding. type ThreadInfo struct { - // TPBase contains the Thread Pointer Base value + // TPBase contains the Thread Pointer Base value. TPBase uint64 - // GPRegs contains the CPU state (registers) for the thread + // GPRegs contains the CPU state (registers) for the thread. GPRegs []byte - // LWP is the Light Weight Process ID (thread ID) + // LWP is the Light Weight Process ID (thread ID). LWP uint32 } -// MachineData contains machine specific information about the process +// MachineData contains machine specific information about the process. type MachineData struct { - // Machine is the Process Machine type + // Machine is the Process Machine type. Machine elf.Machine // CodePACMask contains the PAC mask for code pointers. ARM64 specific, otherwise 0. CodePACMask uint64 @@ -83,7 +83,7 @@ type MachineData struct { DataPACMask uint64 } -// ReadAtCloser interfaces implements io.ReaderAt and io.Closer +// ReadAtCloser combines the io.ReaderAt and io.Closer interfaces. type ReadAtCloser interface { io.ReaderAt io.Closer @@ -94,29 +94,29 @@ type ReadAtCloser interface { // from different goroutines. As an exception the ELFOpener and the returned // GetRemoteMemory object are safe for concurrent use. type Process interface { - // PID returns the process identifier + // PID returns the process identifier. PID() libpf.PID - // GetMachineData reads machine specific data from the target process + // GetMachineData reads machine specific data from the target process. GetMachineData() MachineData - // GetMappings reads and parses process memory mappings + // GetMappings reads and parses process memory mappings. GetMappings() ([]Mapping, uint32, error) - // GetThreads reads the process thread states + // GetThreads reads the process thread states. GetThreads() ([]ThreadInfo, error) - // GetRemoteMemory returns a remote memory reader accessing the target process + // GetRemoteMemory returns a remote memory reader accessing the target process. GetRemoteMemory() remotememory.RemoteMemory - // OpenMappingFile returns ReadAtCloser accessing the backing file of the mapping + // OpenMappingFile returns ReadAtCloser accessing the backing file of the mapping. OpenMappingFile(*Mapping) (ReadAtCloser, error) // GetMappingFileLastModifed returns the timestamp when the backing file was last modified - // or zero if an error occurs or mapping file is not accessible via filesystem + // or zero if an error occurs or mapping file is not accessible via filesystem. GetMappingFileLastModified(*Mapping) int64 - // CalculateMappingFileID calculates FileID of the backing file + // CalculateMappingFileID calculates FileID of the backing file. CalculateMappingFileID(*Mapping) (libpf.FileID, error) // ExtractAsFile returns a filename suitable for opening the given file from