Commit Graph

30 Commits

Author SHA1 Message Date
e928dd898b add go.mod 2022-11-17 14:33:22 +01:00
51fc5ed28d fix loop variable usage 2022-11-17 14:33:09 +01:00
0b3920af52 fix url 2022-11-17 14:32:57 +01:00
d15586390a Lock access to S.cache 2020-01-21 13:38:26 +01:00
5b967134e8 typo fixed: scanner.Run() -> scanner.Errors() 2020-01-19 02:26:15 +01:00
8005624fac less fields required for MAP_CREATE 2020-01-19 02:17:14 +01:00
88f1455dd7 Pure go variant of the ebpf API
Instead of using cgo we call the syscall for BPF directly from go.  The
API hasn't changed, however, and we also closely follow the
C-implementation as given in bpf(2).

Not sure if this pure go variant is beneficial.  Manual maintenance of
all constants and structs upon changes of the BPF API would be necessary
and cumbersome.

We would at least need to complement this with auto-generation of
constants and fields from /usr/include/linux/bpf.h.
2020-01-19 02:05:41 +01:00
d800683dce RunEvery() and better Error-handling added
1. symbolyze.Scanner now implements the RunEvery(time.Duration) method
   that will call scanner.Run() periodically.  It should be called to
   run in its own goroutine.  The loop can be stopped by calling
   scanner.Stop().

2. The scanner now collects all errors from all observers in a private
   error type `errors []error`. It's Error() returns a cumulated list of
   errors, seperated by a newline.
2020-01-18 20:27:23 +01:00
baf998232a Fixed a typo in doc.go 2020-01-16 17:55:37 +01:00
edfb1b1bb7 Added introduction to the documentation 2020-01-16 17:51:40 +01:00
647e704fed Highlight error and add a hint to ptrace_scope
One reason why the call to gdb might fail is that
/proc/sys/kernel/yama/ptrace_scope is set to 1.

We now give an corresponding hint when gdb fails.
2020-01-16 16:02:04 +01:00
afe46025f5 Silence the output of make 2020-01-16 15:56:12 +01:00
de5bcf9913 Cleanup of the comments 2020-01-16 15:47:16 +01:00
3672fd455b Added documentation to ebpf.go 2020-01-16 15:36:06 +01:00
3c7f976acc call defer cmd.Wait() before return 2020-01-16 14:33:02 +01:00
4ba4442100 Better handling of concurrent calls to observers
We now call wg.Add(n) before we loop over n observers.  We also run the
loop inside a goroutine and therefore more quickly handle all (pid,
offset) pairs.
2020-01-16 13:30:41 +01:00
8033525f3f Basic test for ebpf added 2020-01-16 11:24:12 +01:00
509d6e5505 synchronize concurrent access to map in test 2020-01-16 10:50:06 +01:00
3d9ecdca27 Added comments to gdb_test.go 2020-01-16 10:43:30 +01:00
554ae92194 Test added to compare the Scanner vs GDB
gdb_test.go and testdata implement a go test to compare and verify that
we get correct results from the scanner.

testdata/simple.c is a small program that embeds Python and runs the
same code as in runforever.py.  The Makefile compiles this using
python3.7.  Adjustments to the flags might be needed in your environment

gdb_test.go contains only one test, TestSimpleGDB, that
  1. compiles simple.c
  2. runs it multiple times
  3. calls gdb to extract the address of symbol _PyRuntime for each pid
  4. runs our Scanner
  5. compares the results from gdb and our scanner
2020-01-16 10:30:49 +01:00
6eebe8c9f4 Only log the errors from observers
Because we call the observers concurrently, we must not write to S.err
inside the goroutines.  For now, we simply log an error from an
observer.
2020-01-16 10:28:01 +01:00
65a8d52b7a Syncronize all observers in Run()
With the introduction of a sync.WaitGroup we now wait for all observers
to finished before Run() returns
2020-01-16 10:18:07 +01:00
edd9212e89 Rename symbolyze.New -> symbolze.NewScanner 2020-01-16 00:13:03 +01:00
80e5782a45 Added commandline flags 2020-01-16 00:02:59 +01:00
32981d6a55 Don't export *log.Logger in Scanner
By introducing a lowercase type alias 'logger' for *log.Logger we can
now embed 'logger' in Scanner and not export it:

 % go doc Scanner
package symbolyze // import "."

type Scanner struct {
	// Has unexported fields.
}
2020-01-15 23:50:09 +01:00
7af1728eed Cleanup done and documtation added
symbolyze.go has been simplified and cleaned up.  It now also is documented,
f.e.:

 % go doc Scanner
package symbolyze // import "."

type Scanner struct {
	*log.Logger // Embedded logger

	// Has unexported fields.
}
    Scanner represents an engine for scanning for a specific symbol in all
    ELF-files matching a certain pattern. The pattern is described in
    fileapth.Match().

    Once a Scanner is created with New(), it should be populated with Observer
    functions using OnFound(). Optionally, the scanner can be put into debugging
    mode by a call to DebugOn() prior to a call to Run().

    A call to Scanner.Run() then starts the engine and it will scan all pids in
    /proc. Whenever a match is found, all observers will be called with the
    (pid, offset), concurrently.

func New(symbol, pathglob string) *Scanner
func (S *Scanner) DebugOn()
func (S *Scanner) OnFound(fun Observer)
func (S *Scanner) Run() error
2020-01-15 23:26:30 +01:00
fb59ca1072 modular solution, first working draft
symbolyze/ now contains a module that exposes a Finder type with a
simple API, like:

	finder := symbolyze.New("_PyRuntime", "*python3*")
	finder.Debug(true)
	finder.OnFound(mapFD.Set)
	finder.Run()

Instead of writing (pid, offset) directly to a eBPF-map, it implements
an observer-pattern and expects a callback.

TODOs/next steps:

	- Write documentation
	- Add tests
	- Experiment and re-evaluate design
2020-01-15 20:42:53 +01:00
a9f0f27ee2 Rough solution for Tasks 1, 2, 3
main.go:

	- reading /proc
	- iteration over entries in NNN/maps
	- filter glob-search for "*python3*" in pathname
	- find symbol and its offset in pathnanme
	- calculate offset in memory
	- add pid and offset to map

	TODO: encapsulating this into a module

ebpf.go:

	- added type MapFD int, changing all function on a FD to methods
	  This allows us to enrich the data type going forward

	- added bpf_update_elem() from the manpage ebpf2.
	  .updateElement() is the verbatim wrapper to it.

	- added .Add/.Change/.Set methods, which call .updateElement
	  with specific flags

	TODO: re-implement ebpf.go with pure go, using direct syscalls.
2020-01-15 19:04:56 +01:00
64f54c622d first steps of exploration 2020-01-15 12:48:36 +01:00
Sean Heelan
3f6517aae2 Initial import 2020-01-14 14:32:06 +00:00