Documentation ¶
Overview ¶
Package strace implements the logic to print out the input and the return value of each traced syscall.
Package strace supports tracing programs. The basic control of tracing is via a Tracer, which returns raw TraceRecords via a chan. The easiest way to create a Tracer is via RunTracerFromCommand, which uses a filled out exec.Cmd to start a process and produce trace records. Forking is not yet supported.
Index ¶
- Constants
- Variables
- func AlignDown(length int, align uint) int
- func AlignUp(length int, align uint) int
- func CaptureAddress(t *Tracer, addr Addr, addrlen uint32) ([]byte, error)
- func NewProcReader(pid int, addr uintptr) io.Reader
- func NewProcWriter(pid int, addr uintptr) io.Writer
- func ReadMessageHeader64(t *Tracer, addr Addr, msg *abi.MessageHeader64) error
- func Run(root *Tracer) error
- func SysCall(t *Tracer, r *TraceRecord)
- func Wait(wpid int) (int, unix.WaitStatus, error)
- type Addr
- type Address
- type Arg
- type EventType
- type FormatSpecifier
- type FullAddress
- type ProcIO
- type SyscallArgument
- type SyscallArguments
- type SyscallInfo
- type SyscallMap
- type TraceRecord
- type Tracer
- func (t *Tracer) Read(addr Addr, v interface{}) (int, error)
- func (t *Tracer) ReadString(addr Addr, max int) (string, error)
- func (t *Tracer) ReadStringVector(addr Addr, maxsize, maxno int) ([]string, error)
- func (t *Tracer) RunTracerFromCmd(c *exec.Cmd)
- func (t *Tracer) Step(e EventType) (int, error)
- func (t *Tracer) Write(addr Addr, v interface{}) (int, error)
Constants ¶
const ( // ExecMaxTotalSize is the maximum length of all argv and envv entries. // // N.B. The behavior here is different than Linux. Linux provides a limit on // individual arguments of 32 pages, and an aggregate limit of at least 32 pages // but otherwise bounded by min(stack size / 4, 8 MB * 3 / 4). We don't implement // any behavior based on the stack size, and instead provide a fixed hard-limit of // 2 MB (which should work well given that 8 MB stack limits are common). ExecMaxTotalSize = 2 * 1024 * 1024 // ExecMaxElemSize is the maximum length of a single argv or envv entry. ExecMaxElemSize = 32 * 4096 )
From gvisor:
const DefaultLogMaximumSize = 1024
DefaultLogMaximumSize is the default LogMaximumSize.
const Width = 64
Variables ¶
var ByteOrder = binary.LittleEndian
var Debug = func(string, ...interface{}) {}
Debug is a do-nothing function which can be replaced by, e.g., log.Printf
var EventMaximumSize uint
EventMaximumSize determines the maximum size for data blobs (read, write, etc.) sent over the event channel. Default is 0 because most clients cannot do anything useful with binary text dump of byte array arguments.
var LogMaximumSize uint = DefaultLogMaximumSize
LogMaximumSize determines the maximum display size for data blobs (read, write, etc.).
Functions ¶
func CaptureAddress ¶
CaptureAddress pulls a socket address from the process as a byte slice. It returns any errors.
func NewProcReader ¶
NewProcReader returns an io.Reader for a ProcIO.
func NewProcWriter ¶
NewProcWriter returns an io.Writer for a ProcIO.
func ReadMessageHeader64 ¶
func ReadMessageHeader64(t *Tracer, addr Addr, msg *abi.MessageHeader64) error
ReadMessageHeader64 reads a MessageHeader64
func Run ¶
Run runs a set of processes as defined by a Tracer. Because of Unix restrictions around which processes which can trace other processes, Run gets a tad involved. It is implemented as a simple loop, driving events via ptrace commands to processes; and responding to events returned by a Wait. It has to handle a few events specially: o if a wait fails, the process has exited, and must no longer be commanded
this is indicated by a wait followed by an error on PtraceGetRegs
o if a process forks successfully, we must add it to our set of traced processes.
We attach that process, wait for it, then issue a ptrace system call command to it. We don't use the Linux SEIZE command as we can do this in a more generic Unix way.
We create a map of our traced processes and run until it is empty. The initial value of the map is just the one process we start with.
func SysCall ¶
func SysCall(t *Tracer, r *TraceRecord)
SysCall takes a Tracer and a TraceRecord and adds prettyprint to the TraceRecord.
Types ¶
type Address ¶
type Address string
Address is a byte slice cast as a string that represents the address of a network node. Or, in the case of unix endpoints, it may represent a path.
type EventType ¶
type EventType string
EventType describes whether a record is system call Entry or Exit
const ( Enter EventType = "E" Exit = "X" )
type FormatSpecifier ¶
type FormatSpecifier int
FormatSpecifier values describe how an individual syscall argument should be formatted.
const ( // Hex is just a hexadecimal number. Hex FormatSpecifier = iota // Oct is just an octal number. Oct // ReadBuffer is a buffer for a read-style call. The syscall return // value is used for the length. // // Formatted after syscall execution. ReadBuffer // WriteBuffer is a buffer for a write-style call. The following arg is // used for the length. // // Contents omitted after syscall execution. WriteBuffer // ReadIOVec is a pointer to a struct iovec for a writev-style call. // The following arg is used for the length. The return value is used // for the total length. // // Complete contents only formatted after syscall execution. ReadIOVec // WriteIOVec is a pointer to a struct iovec for a writev-style call. // The following arg is used for the length. // // Complete contents only formatted before syscall execution, omitted // after. WriteIOVec // IOVec is a generic pointer to a struct iovec. Contents are not dumped. IOVec // SendMsgHdr is a pointer to a struct msghdr for a sendmsg-style call. // Contents formatted only before syscall execution, omitted after. SendMsgHdr // RecvMsgHdr is a pointer to a struct msghdr for a recvmsg-style call. // Contents formatted only after syscall execution. RecvMsgHdr // Path is a pointer to a char* path. Path // PostPath is a pointer to a char* path, formatted after syscall // execution. PostPath // ExecveStringVector is a NULL-terminated array of strings. Enforces // the maximum execve array length. ExecveStringVector // PipeFDs is an array of two FDs, formatted after syscall execution. PipeFDs // Uname is a pointer to a struct uname, formatted after syscall execution. Uname // Stat is a pointer to a struct stat, formatted after syscall execution. Stat // SockAddr is a pointer to a struct sockaddr. The following arg is // used for length. SockAddr // PostSockAddr is a pointer to a struct sockaddr, formatted after // syscall execution. The following arg is a pointer to the socklen_t // length. PostSockAddr // SockLen is a pointer to a socklen_t, formatted before and after // syscall execution. SockLen // SockFamily is a socket protocol family value. SockFamily // SockType is a socket type and flags value. SockType // SockProtocol is a socket protocol value. Argument n-2 is the socket // protocol family. SockProtocol // SockFlags are socket flags. SockFlags // Timespec is a pointer to a struct timespec. Timespec // PostTimespec is a pointer to a struct timespec, formatted after // syscall execution. PostTimespec // UTimeTimespec is a pointer to a struct timespec. Formatting includes // UTIME_NOW and UTIME_OMIT. UTimeTimespec // ItimerVal is a pointer to a struct itimerval. ItimerVal // PostItimerVal is a pointer to a struct itimerval, formatted after // syscall execution. PostItimerVal // ItimerSpec is a pointer to a struct itimerspec. ItimerSpec // PostItimerSpec is a pointer to a struct itimerspec, formatted after // syscall execution. PostItimerSpec // Timeval is a pointer to a struct timeval, formatted before and after // syscall execution. Timeval // Utimbuf is a pointer to a struct utimbuf. Utimbuf // Rusage is a struct rusage, formatted after syscall execution. Rusage // CloneFlags are clone(2) flags. CloneFlags // OpenFlags are open(2) flags. OpenFlags // Mode is a mode_t. Mode // FutexOp is the futex(2) operation. FutexOp // PtraceRequest is the ptrace(2) request. PtraceRequest // ItimerType is an itimer type (ITIMER_REAL, etc). ItimerType )
Valid FormatSpecifiers.
Unless otherwise specified, values are formatted before syscall execution and not updated after syscall execution (the same value is output).
type FullAddress ¶
type FullAddress struct { // Addr is the network address. Addr Address // Port is the transport port. // // This may not be used by all endpoint types. Port uint16 }
func GetAddress ¶
func GetAddress(t *Tracer, addr []byte) (FullAddress, error)
GetAddress reads an sockaddr struct from the given address and converts it to the FullAddress format. It supports AF_UNIX, AF_INET and AF_INET6 addresses.
type ProcIO ¶
type ProcIO struct {
// contains filtered or unexported fields
}
A ProcIO is used to implement io.Reader and io.Writer. it contains a pid, which is unchanging; and an addr and byte count which change as IO proceeds.
type SyscallArgument ¶
type SyscallArgument struct { // Prefer to use accessor methods instead of 'Value' directly. Value uintptr }
SyscallArgument is an argument supplied to a syscall implementation. The methods used to access the arguments are named after the ***C type name*** and they convert to the closest Go type available. For example, Int() refers to a 32-bit signed integer argument represented in Go as an int32.
Using the accessor methods guarantees that the conversion between types is correct, taking into account size and signedness (i.e., zero-extension vs signed-extension).
func (SyscallArgument) Int ¶
func (a SyscallArgument) Int() int32
Int returns the int32 representation of a 32-bit signed integer argument.
func (SyscallArgument) Int64 ¶
func (a SyscallArgument) Int64() int64
Int64 returns the int64 representation of a 64-bit signed integer argument.
func (SyscallArgument) ModeT ¶
func (a SyscallArgument) ModeT() uint
ModeT returns the int representation of a mode_t argument.
func (SyscallArgument) Pointer ¶
func (a SyscallArgument) Pointer() Addr
Pointer returns the usermem.Addr representation of a pointer argument.
func (SyscallArgument) SizeT ¶
func (a SyscallArgument) SizeT() uint
SizeT returns the uint representation of a size_t argument.
func (SyscallArgument) Uint ¶
func (a SyscallArgument) Uint() uint32
Uint returns the uint32 representation of a 32-bit unsigned integer argument.
func (SyscallArgument) Uint64 ¶
func (a SyscallArgument) Uint64() uint64
Uint64 returns the uint64 representation of a 64-bit unsigned integer argument.
type SyscallArguments ¶
type SyscallArguments [6]SyscallArgument
SyscallArguments represents the set of arguments passed to a syscall.
type SyscallInfo ¶
type SyscallInfo struct {
// contains filtered or unexported fields
}
SyscallInfo captures the name and printing format of a syscall.
type SyscallMap ¶
type SyscallMap map[uintptr]SyscallInfo
SyscallMap maps syscalls into names and printing formats.
type TraceRecord ¶
type TraceRecord struct { EX EventType Regs unix.PtraceRegs Serial int Pid int Err error Errno int Args SyscallArguments Ret [2]SyscallArgument Sysno int Time time.Duration Out string }
TraceRecord has information about a ptrace event.
func (*TraceRecord) FillArgs ¶
func (rec *TraceRecord) FillArgs()
FillArgs pulls the correct registers to populate system call arguments and the system call number into a TraceRecord. Note that the system call number is not technically an argument. This is good, in a sense, since it makes the function arguments end up in "the right place" from the point of view of the caller. The performance improvement is negligible, as you can see by a look at the GNU runtime.
func (*TraceRecord) FillRet ¶
func (rec *TraceRecord) FillRet()
FillRet fills the TraceRecord with the result values from the registers.
func (*TraceRecord) String ¶
func (t *TraceRecord) String() string
String is a stringer for TraceRecords TODO: stringer for Regs.
type Tracer ¶
type Tracer struct { Pid int EX EventType Records chan *TraceRecord Count int Raw bool // Set by the user, it disables pretty printing Name string Printer func(t *Tracer, r *TraceRecord) Last *TraceRecord // contains filtered or unexported fields }
Tracer has information to trace one process. It can be created by starting a command, or attaching. Attaching is not supported yet.
func NewTracerChild ¶
NewTracerChild creates a tracer from a tracer.
func (*Tracer) Read ¶
Read reads from the process at Addr to the interface{} and returns a byte count and error.
func (*Tracer) ReadString ¶
ReadString reads a null-terminated string from the process at Addr and any errors.
func (*Tracer) ReadStringVector ¶
ReadStringVector takes an address, max string size, and max number of string to read, and returns a string slice or error.
func (*Tracer) RunTracerFromCmd ¶
RunTracerFromCommand runs a Tracer given an exec.Cmd. It locks itself down with LockOSThread and will unlock itself when it returns, after the command and all its children exit.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
internal
|
|
abi
Package abi describes the interface between a kernel and userspace.
|
Package abi describes the interface between a kernel and userspace. |
binary
Package binary translates between select fixed-sized types and a binary representation.
|
Package binary translates between select fixed-sized types and a binary representation. |