To build OSv ============ 0) Install perquisite packages: On Fedora: yum install boost-static genromfs libvirt On Debian: apt-get install libboost-all-dev genromfs libvirt 1) make sure all git submodules are uptodate ----------------------------------------- git submodule update --init 2) build the specially patched libunwind ------------------------------------- cd external/libunwind autoreconf -i sh config.sh make cp ./src/.libs/libunwind.a ../.. cd ../.. 4) build the glibc test suite cd external/glibc-testsuite make cd ../.. 5) build osv --------- make To run OSv ========== ./scripts/run.py External Networking =================== To start osv with external networking: $ sudo ./scripts/run.py -n Inside OSv, configure netwroking like so: $ ifconfig virtio-net0 192.168.122.100 netmask 255.255.255.0 up $ route add default gw 192.168.122.1 Test networking: $ test TCPExternalCommunication Debugging ========= To build with debugging symbols, and preemption off (to not confuse gdb), make -j mode=debug conf-preempt=0 To clean debugging build's results, use make clean mode=debug To run the debugging build: ./scripts/run.py -d To connect a debugger to this run: $ gdb build/debug/loader.elf (gdb) connect (gdb) osv syms (gdb) bt To put a breakpoint early in the osv run, a useful trick is tell the vm to reboot after setting the breakpoint: (gdb) hbreak function_name (gdb) monitor system_reset (gdb) c Tracing ======= To add a static tracepoint, use the following code: tracepoint<u64, int> trace_foo("foo", "x=%x y=%d"); ... void foo(u64 x, int y) { trace_foo(x, y); ... } Where trace_foo: an internal identifier "foo": a name for the tracepoint as will be visible in the log <u64, int>: parameters for the tracepoint "x=%x y=%d": format string for the tracepoint; size modifiers unneeded To enable tracepoints at runtime, use the --trace= switch: scripts/imgedit.py setargs build/release/loader.img --trace=sched\* testrunner.so you can use multiple --trace= switches, or a single one with commas. Shell-style wildcards allow enabling multiple tracepoints (as in the example). To trace all function entries/returns in the program, build with conf-tracing=1 (clean build needed), and enable "function*" tracepoints, with --trace=. To view a trace, connect with gdb, and: (gdb) osv syms (gdb) set pagination off (gdb) set logging on (gdb) osv trace gdb.txt will contain the the trace. Leak Detection ============== Memory allocation tracking can be enabled/disabled with the gdb commands "osv leak on", "osv leak off", but even easier is to add the "--leak" paramter to the loader, to have it start leak detection when entering the payload (not during OSv boot). For example: scripts/run.py -e "--leak java.so -jar cli.jar" scripts/run.py -e "--leak tests/tst-leak.so" Leak detection can be used in either the debug or release build, though note that the release builds' optimizations may somewhat modify the reported call traces. When the run ends, connect to OSV with the debugger to see the where the remaining allocation come from: $ gdb build/release/loader.elf # or build/debug/loader.elf (gdb) connect (gdb) osv syms (gdb) set logging on # optional, if you want to save the output to a file (gdb) set height 0 # optional, useful if using "set logging on" (gdb) osv leak show Please note that "osv leak show" can take a L-O-N-G time - even a few minutes, especially when running Java, as it allocates myriads of objects that GDB will now have to inspect. Use-after-free and overrun detection ==================================== Set conf-debug_memory=1 in base.mak, and perform a clean build. A use-after-free will result in an immediate segmentation fault. Note that the detector requires a lot of memory, so you may need to start a larger guest. Running java benchmarks ======================= After running "make", do scripts/imgedit.py setargs build/debug/loader.img java.so -jar bench.jar and then run normally (./scripts/run.py). Profiling ========= You can use 'perf kvm' for profiling: perf kvm --guestvmlinux=build/release/loader.elf top
Nadav Har'El
authored
This patch adds pipe(). The pipes are built using the same FIFO implementation, "af_local_buffer", as used by the existing unix-domain socketpair implementation - while the socket-pair used two of these buffers, a pipe uses one. This implementation deviates from traditional POSIX pipe behavior in two ways that we should fix in followup-patches: 1. SIGPIPE is not supported: A write to a pipe whose read end is closed will always return EPIPE, and not generate a SIGPIPE signal. Programs that rely on SIGPIPE will break, but SIGPIPE is completely out of fashion, and normally ignored. 2. Unix-style "atomic writes" are not obeyed. A write(), even if smaller than PIPE_BUF (=4096 on Linux, whose ABI we're emulating), may partially succeed if the pipe's buffer is nearly full. Only a write() of a single byte is guaranteed to be atomic. We hope that Java doesn't rely on multi-byte write() atomicity (single-byte writes are enough for waking poll, for example), and users of Java's "Pipe" class definitely can't (as Java is not Posix-only), so we hope this will not cause problems. Fixing this issue (which is easy) is left as a TODO in the code. Additionally, this patch marks with a FIXME (but doesn't fix) a serious bug in the code's iovec handling, so writev() and readv() are expected not to work in this version of pipe() - and also on the existing socketpair.