Commit bb34fe7e authored by 4ast's avatar 4ast

Merge pull request #160 from iovisor/bblanco_dev

Add field support to trace_print and friends
parents ee286326 022f3d77
...@@ -6,14 +6,13 @@ ...@@ -6,14 +6,13 @@
# sudo ./hello_world.py" # sudo ./hello_world.py"
from bpf import BPF from bpf import BPF
from subprocess import call
prog = """ prog = """
int hello(void *ctx) { int hello(void *ctx) {
bpf_trace_printk("Hello, World!\\n"); bpf_trace_printk("Hello, World!\\n");
return 0; return 0;
}; }
""" """
b = BPF(text=prog) b = BPF(text=prog)
b.attach_kprobe(event="sys_clone", fn_name="hello") b.attach_kprobe(event="sys_clone", fn_name="hello")
b.trace_print() b.trace_print(fmt="{1} {5}")
...@@ -389,7 +389,7 @@ class BPF(object): ...@@ -389,7 +389,7 @@ class BPF(object):
if res < 0: if res < 0:
raise Exception("Failed to attach BPF to kprobe") raise Exception("Failed to attach BPF to kprobe")
open_kprobes[ev_name] = res open_kprobes[ev_name] = res
return res return self
@staticmethod @staticmethod
def detach_kprobe(event): def detach_kprobe(event):
...@@ -412,7 +412,7 @@ class BPF(object): ...@@ -412,7 +412,7 @@ class BPF(object):
if res < 0: if res < 0:
raise Exception("Failed to attach BPF to kprobe") raise Exception("Failed to attach BPF to kprobe")
open_kprobes[ev_name] = res open_kprobes[ev_name] = res
return res return self
@staticmethod @staticmethod
def detach_kretprobe(event): def detach_kretprobe(event):
...@@ -437,14 +437,33 @@ class BPF(object): ...@@ -437,14 +437,33 @@ class BPF(object):
if not tracefile: if not tracefile:
tracefile = open("%s/trace_pipe" % TRACEFS) tracefile = open("%s/trace_pipe" % TRACEFS)
if nonblocking: if nonblocking:
fd = trace.fileno() fd = tracefile.fileno()
fl = fcntl.fcntl(fd, fcntl.F_GETFL) fl = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
return tracefile return tracefile
@staticmethod @staticmethod
def trace_readline(nonblocking=True): def trace_readline_fields(nonblocking=False):
"""trace_readline(nonblocking=True) """trace_readline_fields(nonblocking=False)
Read from the kernel debug trace pipe and return a tuple of the
fields (task, pid, cpu, flags, timestamp, msg) or None if no
line was read (nonblocking=True)
"""
line = BPF.trace_readline(nonblocking)
if line:
task = line[:16].lstrip()
line = line[17:]
ts_end = line.find(":")
pid, cpu, flags, ts = line[:ts_end].split()
cpu = cpu[1:-1]
msg = line[ts_end + 4:]
return (task, int(pid), int(cpu), flags, float(ts), msg)
return
@staticmethod
def trace_readline(nonblocking=False):
"""trace_readline(nonblocking=False)
Read from the kernel debug trace pipe and return one line Read from the kernel debug trace pipe and return one line
If nonblocking is False, this will block until ctrl-C is pressed. If nonblocking is False, this will block until ctrl-C is pressed.
...@@ -454,17 +473,28 @@ class BPF(object): ...@@ -454,17 +473,28 @@ class BPF(object):
line = None line = None
try: try:
line = trace.readline(128).rstrip() line = trace.readline(1024).rstrip()
except BlockingIOError: except IOError:
pass pass
except KeyboardInterrupt:
exit()
return line return line
@staticmethod @staticmethod
def trace_print(): def trace_print(fmt=None):
try: """trace_print(fmt=None)
while True:
Read from the kernel debug trace pipe and print on stdout.
If fmt is specified, apply as a format string to the output. See
trace_readline_fields for the members of the tuple
example: trace_print(fmt="pid {1}, msg = {5}")
"""
while True:
if fmt:
fields = BPF.trace_readline_fields(nonblocking=False)
line = fmt.format(*fields)
else:
line = BPF.trace_readline(nonblocking=False) line = BPF.trace_readline(nonblocking=False)
print(line) print(line)
sys.stdout.flush() sys.stdout.flush()
except KeyboardInterrupt:
exit()
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