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