Commit 7eb074a7 authored by 4ast's avatar 4ast

Merge pull request #163 from iovisor/bblanco_dev

Add debug flag to enable prints from kernel verifier
parents 88fda697 b71f9fa6
......@@ -122,8 +122,6 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
const char *license, unsigned kern_version,
char *log_buf, unsigned log_buf_size)
{
log_buf = log_buf ? log_buf : bpf_log_buf;
log_buf_size = log_buf_size ? log_buf_size : LOG_BUF_SIZE;
union bpf_attr attr = {
.prog_type = prog_type,
.insns = ptr_to_u64((void *) insns),
......@@ -131,14 +129,19 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
.license = ptr_to_u64((void *) license),
.log_buf = ptr_to_u64(log_buf),
.log_size = log_buf_size,
.log_level = 1,
.log_level = log_buf ? 1 : 0,
};
attr.kern_version = kern_version;
log_buf[0] = 0;
if (log_buf)
log_buf[0] = 0;
int ret = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
if (ret < 0 && log_buf == bpf_log_buf) {
if (ret < 0 && !log_buf) {
// caller did not specify log_buf but failure should be printed,
// so call recursively and print the result to stderr
bpf_prog_load(prog_type, insns, prog_len, license, kern_version,
bpf_log_buf, LOG_BUF_SIZE);
fprintf(stderr, "bpf: %s\n%s\n", strerror(errno), bpf_log_buf);
}
return ret;
......
......@@ -259,6 +259,21 @@ class BPF(object):
return filename
def __init__(self, src_file="", hdr_file="", text=None, debug=0):
"""Create a a new BPF module with the given source code.
Note:
All fields are marked as optional, but either `src_file` or `text`
must be supplied, and not both.
Args:
src_file (Optional[str]): Path to a source file for the module
hdr_file (Optional[str]): Path to a helper header file for the `src_file`
text (Optional[str]): Contents of a source file for the module
debug (Optional[int]): Flags used for debug prints, can be |'d together
0x1: print LLVM IR to stderr
0x2: print BPF bytecode to stderr
"""
self.debug = debug
self.funcs = {}
self.tables = {}
......@@ -284,16 +299,19 @@ class BPF(object):
if lib.bpf_function_start(self.module, func_name.encode("ascii")) == None:
raise Exception("Unknown program %s" % func_name)
log_buf = ct.create_string_buffer(65536) if self.debug else None
fd = lib.bpf_prog_load(prog_type,
lib.bpf_function_start(self.module, func_name.encode("ascii")),
lib.bpf_function_size(self.module, func_name.encode("ascii")),
lib.bpf_module_license(self.module),
lib.bpf_module_kern_version(self.module),
None, 0)
log_buf, ct.sizeof(log_buf) if log_buf else 0)
if self.debug & 0x2:
print(log_buf.value.decode(), file=sys.stderr)
if fd < 0:
print((ct.c_char * 65536).in_dll(lib, "bpf_log_buf").value)
#print(ct.c_char_p.in_dll(lib, "bpf_log_buf").value)
raise Exception("Failed to load BPF program %s" % func_name)
fn = BPF.Function(self, func_name, fd)
......
......@@ -4,7 +4,6 @@
from bpf import BPF
import os
from socket import socket, AF_INET, SOCK_DGRAM
import sys
from unittest import main, TestCase
......@@ -23,18 +22,13 @@ class TestKprobeRgx(TestCase):
return 0;
}
""")
self.b.attach_kprobe(event_re="^SyS_send.*", fn_name="hello",
pid=0, cpu=-1)
self.b.attach_kretprobe(event_re="^SyS_send.*", fn_name="goodbye",
pid=1, cpu=-1)
self.b.attach_kprobe(event_re="^SyS_bp.*", fn_name="hello")
self.b.attach_kretprobe(event_re="^SyS_bp.*", fn_name="goodbye")
def test_send1(self):
udp = socket(AF_INET, SOCK_DGRAM)
udp.sendto(b"a" * 10, ("127.0.0.1", 5000))
udp.close()
k1 = self.b["stats"].Key(1)
k2 = self.b["stats"].Key(2)
self.assertEqual(self.b["stats"][k1].val, self.b["stats"][k2].val)
self.assertEqual(self.b["stats"][k1].val, self.b["stats"][k2].val + 1)
if __name__ == "__main__":
main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment