stuff
This commit is contained in:
parent
6ef1dcd81a
commit
306a13f866
|
@ -0,0 +1,5 @@
|
||||||
|
eBPF experiments
|
||||||
|
|
||||||
|
Installing requirements on a Debian-esque:
|
||||||
|
|
||||||
|
sudo apt-get install python3-bpfcc
|
|
@ -0,0 +1,59 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from bcc import BPF
|
||||||
|
|
||||||
|
|
||||||
|
DEBUG_FLAGS = {
|
||||||
|
"ir": 0x1, # debug output compiled LLVM IR
|
||||||
|
"bpf": 0x2, # debug output loaded BPF bytecode and register state on branches.
|
||||||
|
"pp": 0x4, # debug output pre-processor result.
|
||||||
|
"src": 0x8, # debug output ASM instructions embedded with source.
|
||||||
|
"reg": 0x10, # debug output register state on all instructions in addition to DEBUG_BPF.
|
||||||
|
"btf": 0x20, # debug BTF
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_debug_flags(args: str) -> int:
|
||||||
|
if not args.strip():
|
||||||
|
return 0
|
||||||
|
|
||||||
|
flags = [arg.strip() for arg in args.split(",")]
|
||||||
|
debug = 0
|
||||||
|
for flag in flags:
|
||||||
|
debug |= DEBUG_FLAGS[flag]
|
||||||
|
return debug
|
||||||
|
|
||||||
|
|
||||||
|
def load_program(debug_args: str, program_source: str) -> BPF:
|
||||||
|
debug_flags = get_debug_flags(debug_args)
|
||||||
|
|
||||||
|
program: str
|
||||||
|
if program_source == "-":
|
||||||
|
print('LD: STDIN')
|
||||||
|
program = sys.stdin.read()
|
||||||
|
else:
|
||||||
|
print('LD: {}'.format(program_source))
|
||||||
|
with open(program_source) as source_file:
|
||||||
|
program = source_file.read()
|
||||||
|
|
||||||
|
bpf = BPF(text=program, debug=debug_flags)
|
||||||
|
print('LD: OK')
|
||||||
|
return bpf
|
||||||
|
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
bpf = load_program(args.debug, args.path)
|
||||||
|
print('RUN')
|
||||||
|
bpf.trace_print()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(prog="bpf", description="Run BPF programs")
|
||||||
|
parser.add_argument("--debug", "-d", help="debug flags", default="")
|
||||||
|
parser.add_argument("path", help="program source")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
main(args)
|
|
@ -0,0 +1,5 @@
|
||||||
|
int kprobe__sys_clone(void *ctx)
|
||||||
|
{
|
||||||
|
bpf_trace_printk("Hello, world\n");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from bcc import BPF
|
||||||
|
|
||||||
|
program = """
|
||||||
|
int
|
||||||
|
kprobe__sys_clone(void *ctx)
|
||||||
|
{
|
||||||
|
bpf_trace_printk("Hello, world\\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
print('LD PROG')
|
||||||
|
b = BPF(text=program)
|
||||||
|
print('TRC PRN')
|
||||||
|
b.trace_print()
|
|
@ -0,0 +1,5 @@
|
||||||
|
int kprobe__sys_read(void *ctx)
|
||||||
|
{
|
||||||
|
bpf_trace_printk("Hello, world\n");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
bcc
|
|
@ -0,0 +1,57 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
# lexer(tokeniser)->parser->code generator
|
||||||
|
|
||||||
|
class Tokenizer
|
||||||
|
TOKEN_TYPES = [
|
||||||
|
[:def, /\bdef\b/],
|
||||||
|
[:end, /\bend\b/],
|
||||||
|
[:identifier, /\b[a-zA-Z]+\b/],
|
||||||
|
[:integer, /\b[0-9]+\b/],
|
||||||
|
[:oparen, /\(/],
|
||||||
|
[:cparen, /\)/],
|
||||||
|
]
|
||||||
|
|
||||||
|
def initialize(code)
|
||||||
|
@code = code
|
||||||
|
end
|
||||||
|
|
||||||
|
def tokenize
|
||||||
|
tokens = []
|
||||||
|
until @code.empty?
|
||||||
|
token = tokenize_one
|
||||||
|
tokens << token
|
||||||
|
@code = @code.strip
|
||||||
|
end
|
||||||
|
return tokens
|
||||||
|
end
|
||||||
|
|
||||||
|
def tokenize_one
|
||||||
|
TOKEN_TYPES.each do |type, re|
|
||||||
|
re = /\A(#{re})/
|
||||||
|
if @code =~ re
|
||||||
|
value = $1
|
||||||
|
@code = @code[value.length..-1]
|
||||||
|
return Token.new(type, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Token = Struct.new(:type, :value)
|
||||||
|
|
||||||
|
# 11m30s
|
||||||
|
class Parser
|
||||||
|
def initialize(tokens)
|
||||||
|
@tokens = tokens
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
tokens = Tokenizer.new(File.read("test.src")).tokenize
|
||||||
|
puts tokens.map(&:inspect).join("\n")
|
||||||
|
tree = Parser.new(tokens).parse
|
||||||
|
p tree
|
|
@ -0,0 +1,2 @@
|
||||||
|
def f() 1 end
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# see https://www.solipsys.co.uk/new/PowersOfTwoInLexOrder.html?sg28hn
|
||||||
|
# compare some_stats(9) with some_stats(100). After 9, the standard
|
||||||
|
# deviation and variance start to rise quickly.
|
||||||
|
|
||||||
|
import statistics
|
||||||
|
|
||||||
|
def oddities(n):
|
||||||
|
ns = []
|
||||||
|
for i in range(1, n+1):
|
||||||
|
v = 2 ** i
|
||||||
|
v = str(v)
|
||||||
|
ns.append(v)
|
||||||
|
ns.sort()
|
||||||
|
return [float(v[0] + '.' + v[1:]) for v in ns]
|
||||||
|
|
||||||
|
def evenities(n):
|
||||||
|
ns = []
|
||||||
|
for i in range(1, n+1):
|
||||||
|
v = 10 ** (i / 10.)
|
||||||
|
ns.append(v)
|
||||||
|
return ns
|
||||||
|
|
||||||
|
def differences(n):
|
||||||
|
ons = oddities(n)
|
||||||
|
ens = evenities(n)
|
||||||
|
print(ons)
|
||||||
|
print(ens)
|
||||||
|
deltas = [abs(ens[i] - ons[i]) for i in range(len(ons))]
|
||||||
|
return deltas
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def some_stats(n):
|
||||||
|
deltas = differences(n)
|
||||||
|
print('Min: {}'.format(min(deltas)))
|
||||||
|
print('Avg: {}'.format(sum(deltas) / len(deltas)))
|
||||||
|
print('Max: {}'.format(max(deltas)))
|
||||||
|
print(' Std dev: {}'.format(statistics.stdev(deltas)))
|
||||||
|
print('Variance: {}'.format(statistics.variance(deltas)))
|
Loading…
Reference in New Issue