Documentation ¶
Index ¶
- func ComposePostProcessors(ctx context.Context, input <-chan OutputLine, posts ...PostProcessor) <-chan OutputLine
- func ComposePreProcessors(ctx context.Context, input <-chan InputLine, pres ...PreProcessor) <-chan InputLine
- func ComposeProcessors(ctx context.Context, input <-chan InputLine, proc Processor) <-chan OutputLine
- func Consume(input <-chan OutputLine)
- func GetLineJson(line []Node) ([]byte, error)
- func StartParsing(ctx context.Context, reader io.Reader) <-chan InputLine
- type BacktraceElement
- type BacktracePresenter
- type BasicPresenter
- type CloudRepo
- type ColorCode
- type CompositeRepo
- type ContextPresenter
- type Demuxer
- type DummySource
- type DumpEntry
- type DumpHandler
- type DumpfileElement
- type Entry
- type FileCloser
- type Filter
- type IDsTxtRepo
- type Index
- type InputLine
- type LLVMSymbolizeResult
- type LLVMSymbolizer
- type LineHeader
- type LineSource
- type LogLine
- type MappingElement
- type Module
- type ModuleElement
- type NewBuildIDRepo
- type Node
- type NodeVisitor
- type NopFileCloser
- type OptStr
- type OptimizeColor
- type OutputLine
- type PCElement
- type ParseLineFunc
- type PostProcessor
- type PreProcessor
- type Process
- type Processor
- type Repository
- type ResetElement
- type Segment
- type SourceLocation
- type Symbolizer
- type Text
- type TriggerContext
- type TriggerTap
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ComposePostProcessors ¶
func ComposePostProcessors(ctx context.Context, input <-chan OutputLine, posts ...PostProcessor) <-chan OutputLine
ComposePostProcessors takes several PostProcessors and runs them in sequence
func ComposePreProcessors ¶
func ComposePreProcessors(ctx context.Context, input <-chan InputLine, pres ...PreProcessor) <-chan InputLine
ComposePreProcessors takes several PreProcessors and runs them in sequence
func ComposeProcessors ¶
func ComposeProcessors(ctx context.Context, input <-chan InputLine, proc Processor) <-chan OutputLine
Compose takes a single Processor and causes it to start transforming Input into Output
func Consume ¶
func Consume(input <-chan OutputLine)
Consume eats and forgets all input from a channel. This is useful for keeping a goroutine alive until a pipeline has finished processing to completion.
func GetLineJson ¶
Types ¶
type BacktraceElement ¶
type BacktraceElement struct {
// contains filtered or unexported fields
}
func (*BacktraceElement) Accept ¶
func (b *BacktraceElement) Accept(visitor NodeVisitor)
type BacktracePresenter ¶
type BacktracePresenter struct {
// contains filtered or unexported fields
}
BacktracePresenter intercepts backtrace elements on their own line and presents them in text. Inlines are output as separate lines. A PostProcessor is taken as an input to synchronously compose another PostProcessor
func NewBacktracePresenter ¶
func NewBacktracePresenter(out io.Writer, next PostProcessor) *BacktracePresenter
NewBacktracePresenter constructs a BacktracePresenter.
Example ¶
// mock the input and outputs of llvm-symbolizer symbo := newMockSymbolizer([]mockModule{ { filepath.Join(*testDataDir, "libc.elf"), map[uint64][]SourceLocation{ 0x429c0: {{NewOptStr("math.h"), 51, NewOptStr("__DOUBLE_FLOAT")}, {NewOptStr("atan2.c"), 49, NewOptStr("atan2")}}, 0x43680: {{NewOptStr("pow.c"), 23, NewOptStr("pow")}}, 0x44987: {{NewOptStr("memcpy.c"), 76, NewOptStr("memcpy")}}, }, }, { filepath.Join(*testDataDir, "libcrypto.elf"), map[uint64][]SourceLocation{ 0x81000: {{NewOptStr("rsa.c"), 101, NewOptStr("mod_exp")}}, 0x82000: {{NewOptStr("aes.c"), 17, NewOptStr("gf256_mul")}}, 0x83000: {{NewOptStr("aes.c"), 560, NewOptStr("gf256_div")}}, }, }, }) // make a demuxer demuxer := NewDemuxer(getTestBinaries(), symbo) // define a little message that will need to be parsed msg := "[131.200] 1234.5678> {{{module:1:libc.so:elf:4fcb712aa6387724a9f465a32cd8c14b}}}\n" + "[131.301] 1234.5678> {{{module:9:libcrypto.so:elf:12ef5c50b3ed3599c07c02d4509311be}}}\n" + "[131.301] 1234.5678> {{{module:3:libmissing.no:elf:deadbeef}}}\n" + "[131.402] 1234.5678> {{{mmap:0x12345000:0xcf6bc:load:1:rx:0x0}}}\n" + "[131.503] 1234.5678> {{{mmap:0x23456000:0x83c80:load:09:rx:0x80000}}}\n" + "[131.503] 1234.5678> {{{mmap:0x34567000:0x1000:load:3:rx:0x0}}}\n" + "[131.604] 1234.5678> Backtrace:\n" + "[131.604] 1234.5678> {{{bt:0:0x12388680}}}\n" + "[131.604] 1234.5678> {{{bt:1:0x23457000}}}\n" + "[131.604] 1234.5678> {{{bt:2:0x123879c0}}}\n" + "[131.705] 1234.5678> {{{bt:3:0x34567042}}}\n" // start sending InputLines to the demuxer ctx := context.Background() in := StartParsing(ctx, strings.NewReader(msg)) // start the demuxer which will cause filters to send output lines to 'out' out := demuxer.Start(ctx, in) Consume(ComposePostProcessors(ctx, out, &ContextPresenter{}, NewBacktracePresenter(os.Stdout, NewBasicPresenter(os.Stdout, false))))
Output: [131.604] 01234.05678> [[[ELF module #0x1 "libc.so" BuildID=4fcb712aa6387724a9f465a32cd8c14b 0x12345000]]] [131.604] 01234.05678> [[[ELF module #0x3 "libmissing.no" BuildID=deadbeef 0x34567000]]] [131.604] 01234.05678> [[[ELF module #0x9 "libcrypto.so" BuildID=12ef5c50b3ed3599c07c02d4509311be 0x23456000]]] [131.604] 01234.05678> Backtrace: [131.604] 01234.05678> #0 0x0000000012388680 in pow pow.c:23 <libc.so>+0x43680 [131.604] 01234.05678> #1 0x0000000023457000 in mod_exp rsa.c:101 <libcrypto.so>+0x81000 [131.604] 01234.05678> #2.1 0x00000000123879c0 in __DOUBLE_FLOAT math.h:51 <libc.so>+0x429c0 [131.604] 01234.05678> #2 0x00000000123879c0 in atan2 atan2.c:49 <libc.so>+0x429c0 [131.705] 01234.05678> #3 0x0000000034567042 in <libmissing.no>+0x42
func (*BacktracePresenter) Process ¶
func (b *BacktracePresenter) Process(line OutputLine, out chan<- OutputLine)
type BasicPresenter ¶
type BasicPresenter struct {
// contains filtered or unexported fields
}
BasicPresenter is a presenter to output very basic uncolored output
func NewBasicPresenter ¶
func NewBasicPresenter(output io.Writer, enableColor bool) *BasicPresenter
func (*BasicPresenter) Process ¶
func (b *BasicPresenter) Process(res OutputLine, out chan<- OutputLine)
type CloudRepo ¶
type CloudRepo struct {
// contains filtered or unexported fields
}
CloudRepo represents a repository stored in a GCS path.
func NewCloudRepo ¶
NewCloudRepo creates a CloudRepo using gcsURL. The connection to the bucket will be ended when ctx is canceled. No timeout on GetBuildObject is set until SetTimeout is called.
func (*CloudRepo) GetBuildObject ¶
func (c *CloudRepo) GetBuildObject(buildID string) (FileCloser, error)
GetBuildObject checks the cache for the debug object. If available it uses that. Otherwise it downloads the object, adds it to the cache, and returns the local reference.
func (*CloudRepo) SetTimeout ¶
SetTimeout sets the maximum duration that GetBuildObject will wait before canceling the download from GCS.
type ColorCode ¶
type ColorCode struct {
// contains filtered or unexported fields
}
TODO(jakehehrlich): Make this semantic rather than literal (e.g. keep track of color/bold information directly) ColorCode is an AST node representing a colored part of the markup
func (*ColorCode) Accept ¶
func (c *ColorCode) Accept(visitor NodeVisitor)
type CompositeRepo ¶
type CompositeRepo struct {
// contains filtered or unexported fields
}
func (*CompositeRepo) AddRepo ¶
func (c *CompositeRepo) AddRepo(repo Repository)
AddRepo adds a repo to be checked that has lower priority than any other previouslly added repo. This operation is not thread safe.
func (*CompositeRepo) GetBuildObject ¶
func (c *CompositeRepo) GetBuildObject(buildID string) (FileCloser, error)
type ContextPresenter ¶
type ContextPresenter map[LineSource]map[uint64]dsoInfo
func (ContextPresenter) Process ¶
func (c ContextPresenter) Process(line OutputLine, out chan<- OutputLine)
type Demuxer ¶
type Demuxer struct {
// contains filtered or unexported fields
}
Demuxer demultiplexes incomming input lines, spins up new filters, and sends them input lines.
func NewDemuxer ¶
func NewDemuxer(repo Repository, symbo Symbolizer) *Demuxer
NewDemuxer creates a new demuxer.
type DummySource ¶
type DummySource struct{}
type DumpHandler ¶
type DumpHandler struct {
// contains filtered or unexported fields
}
func (*DumpHandler) HandleDump ¶
func (d *DumpHandler) HandleDump(dump *DumpfileElement)
type DumpfileElement ¶
type DumpfileElement struct {
// contains filtered or unexported fields
}
func (*DumpfileElement) Accept ¶
func (d *DumpfileElement) Accept(visitor NodeVisitor)
func (*DumpfileElement) Context ¶
func (d *DumpfileElement) Context() TriggerContext
func (*DumpfileElement) Name ¶
func (d *DumpfileElement) Name() string
func (*DumpfileElement) SinkType ¶
func (d *DumpfileElement) SinkType() string
type FileCloser ¶
FileCloser holds a reference to a file and prevents it from being deleted until after Close() is called. The filename can be retrieved via String()
type Filter ¶
type Filter struct {
// contains filtered or unexported fields
}
Filter represents the state needed to process a log.
func NewFilter ¶
func NewFilter(repo Repository, symbo Symbolizer) *Filter
NewFilter creates a new filter
type IDsTxtRepo ¶
type IDsTxtRepo struct {
// contains filtered or unexported fields
}
idsSource is a BinaryFileSource parsed from ids.txt
func NewIDsTxtRepo ¶
func NewIDsTxtRepo(pathToIDs string, rel bool) *IDsTxtRepo
func (*IDsTxtRepo) GetBuildObject ¶
func (i *IDsTxtRepo) GetBuildObject(buildID string) (FileCloser, error)
type LLVMSymbolizeResult ¶
type LLVMSymbolizeResult struct { Locs []SourceLocation Err error }
type LLVMSymbolizer ¶
type LLVMSymbolizer struct {
// contains filtered or unexported fields
}
func NewLLVMSymbolizer ¶
func NewLLVMSymbolizer(llvmSymboPath string, restartInterval uint) *LLVMSymbolizer
func (*LLVMSymbolizer) FindSrcLoc ¶
func (s *LLVMSymbolizer) FindSrcLoc(file, build string, modRelAddr uint64) <-chan LLVMSymbolizeResult
type LineHeader ¶
type LineHeader interface {
Present() string
}
type LineSource ¶
type LineSource interface{}
TODO (jakehehrlich): LineSource is now a part of the public interface. This is needed to allow for the proper construction of triggers since triggers need to know where a triggering element came from. Right now this is just an empty interface. It would be nice if the user could do soemthing other than cast this.
type MappingElement ¶
type MappingElement struct {
// contains filtered or unexported fields
}
MappingElement represents an mmap element in the markup
func (*MappingElement) Accept ¶
func (s *MappingElement) Accept(visitor NodeVisitor)
type ModuleElement ¶
type ModuleElement struct {
// contains filtered or unexported fields
}
ModuleElement represents a module element in the markup
func (*ModuleElement) Accept ¶
func (m *ModuleElement) Accept(visitor NodeVisitor)
type NewBuildIDRepo ¶
type NewBuildIDRepo string
func (NewBuildIDRepo) GetBuildObject ¶
func (b NewBuildIDRepo) GetBuildObject(buildID string) (FileCloser, error)
type Node ¶
type Node interface {
Accept(visitor NodeVisitor)
}
type NodeVisitor ¶
type NodeVisitor interface { VisitBt(elem *BacktraceElement) VisitPc(elem *PCElement) VisitColor(node *ColorCode) VisitText(node *Text) VisitDump(elem *DumpfileElement) VisitReset(elem *ResetElement) VisitModule(elem *ModuleElement) VisitMapping(elem *MappingElement) }
NodeVisitor is a visitor for all Node types
type NopFileCloser ¶
type NopFileCloser string
func (NopFileCloser) Close ¶
func (d NopFileCloser) Close() error
func (NopFileCloser) String ¶
func (d NopFileCloser) String() string
type OptStr ¶
type OptStr struct {
// contains filtered or unexported fields
}
OptionalString implements possibly missing strings from llvm-symbolizer
func EmptyOptStr ¶
func EmptyOptStr() OptStr
func (OptStr) MarshalJSON ¶
type OptimizeColor ¶
type OptimizeColor struct { }
OptimizeColor attempts to transform output elements to use as few color transisitions as is possible
func (*OptimizeColor) Process ¶
func (o *OptimizeColor) Process(line OutputLine, out chan<- OutputLine)
type OutputLine ¶
type OutputLine struct { LogLine // contains filtered or unexported fields }
type PCElement ¶
type PCElement struct {
// contains filtered or unexported fields
}
PcElement is an AST node representing a pc element in the markup
func (*PCElement) Accept ¶
func (p *PCElement) Accept(visitor NodeVisitor)
type ParseLineFunc ¶
func GetLineParser ¶
func GetLineParser() ParseLineFunc
type PostProcessor ¶
type PostProcessor interface {
Process(OutputLine, chan<- OutputLine)
}
PostProcessor is the type of modifications to a stream of OutputLines
type PreProcessor ¶
PreProcessor is the type of modifications to a stream of InputLines
type Processor ¶
type Processor interface {
Process(InputLine, chan<- OutputLine)
}
Processor is the type of transformations from OutputLines to InputLines
type Repository ¶
type Repository interface { // GetBuildObject takes a build ID and returns the corresponding file // reference via a FileCloser. GetBuildObject(buildID string) (FileCloser, error) }
Repository represents a collection of debug binaries referable to by filepath and indexed by their build ID.
type ResetElement ¶
type ResetElement struct{}
func (*ResetElement) Accept ¶
func (r *ResetElement) Accept(visitor NodeVisitor)
type Segment ¶
type Segment struct { Mod uint64 `json:"mod"` Vaddr uint64 `json:"vaddr"` Size uint64 `json:"size"` Flags string `json:"flags"` ModRelAddr uint64 `json:"mod_rel_addr"` }
Later this will be more general.
type SourceLocation ¶
type SourceLocation struct {
// contains filtered or unexported fields
}
SourceLocation represents a location in a source file
type Symbolizer ¶
type Symbolizer interface {
FindSrcLoc(file, build string, modRelAddr uint64) <-chan LLVMSymbolizeResult
}
Symbolizer is an interface to an object that maps addresses in a bianry to source locations
type Text ¶
type Text struct {
// contains filtered or unexported fields
}
Text represents text between the special parts of the markup
func (*Text) Accept ¶
func (t *Text) Accept(visitor NodeVisitor)
type TriggerContext ¶
type TriggerContext struct { Source LineSource Mods []Module Segs []Segment }
TriggerHandler is a visitor for Node types that can trigger actions
type TriggerTap ¶
type TriggerTap struct {
// contains filtered or unexported fields
}
TriggerTap is a nop on the pipeline that reads trigger information out
func NewTriggerTap ¶
func NewTriggerTap() *TriggerTap
func (*TriggerTap) AddHandler ¶
func (t *TriggerTap) AddHandler(handler func(*DumpfileElement))
func (*TriggerTap) Process ¶
func (t *TriggerTap) Process(line OutputLine, out chan<- OutputLine)