Skip to content

Commit

Permalink
Merge pull request #67 from arighi/drgn-support
Browse files Browse the repository at this point in the history
virtme-ng: generate drgn compatible memory dumps
  • Loading branch information
Andrea Righi authored Feb 9, 2024
2 parents a28ac8b + 9a44e8f commit e77655a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 8 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,26 @@ Examples
(virtme-ng is started in graphical mode)
```

- Generate a memory dump of a running instance and read 'jiffies' from the
memory dump using the drgn debugger:
````
# Start the vng instance in debug mode
$ vng --debug
# In a separate shell session trigger the memory dump to /tmp/vmcore.img
$ vng --dump /tmp/vmcore.img
# Use drgn to read 'jiffies' from the memory dump:
$ echo "print(prog['jiffies'])" | drgn -q -s vmlinux -c /tmp/vmcore.img
drgn 0.0.23 (using Python 3.11.6, elfutils 0.189, with libkdumpfile)
For help, type help(drgn).
>>> import drgn
>>> from drgn import NULL, Object, cast, container_of, execscript, offsetof, reinterpret, sizeof
>>> from drgn.helpers.common import *
>>> from drgn.helpers.linux import *
>>> (volatile unsigned long)4294675464
```
- Run virtme-ng inside a docker container:
```
$ docker run -it ubuntu:22.04 /bin/bash
Expand Down
3 changes: 3 additions & 0 deletions virtme/commands/configkernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ def arg_fail(message):
"CONFIG_UPROBES=y",
"CONFIG_UPROBE_EVENTS=y",
"CONFIG_DEBUG_FS=y",
"# Required to generate memory dumps for drgn",
"CONFIG_FW_CFG_SYSFS=y",
"CONFIG_FW_CFG_SYSFS_CMDLINE=y",
"# Graphics support",
"CONFIG_DRM=y",
"CONFIG_DRM_VIRTIO_GPU=y",
Expand Down
16 changes: 8 additions & 8 deletions virtme_ng/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,9 @@ def _get_virtme_sound(self, args):
self.virtme_param["sound"] = ""

def _get_virtme_disable_microvm(self, args):
if args.disable_microvm:
# Automatically disable microvm in debug mode, since it seems to
# produce incomplete memory dumps.
if args.disable_microvm or args.debug:
self.virtme_param["disable_microvm"] = "--disable-microvm"
else:
self.virtme_param["disable_microvm"] = ""
Expand Down Expand Up @@ -951,7 +953,10 @@ def _get_virtme_qemu_opts(self, args):
if args.qemu_opts is not None:
qemu_args += " ".join(args.qemu_opts)
if args.debug:
qemu_args += "-s -qmp tcp:localhost:3636,server,nowait"
# Enable vmcoreinfo (required by drgn memory dumps)
qemu_args += "-device vmcoreinfo "
# Enable debug mode and QMP (to trigger memory dump via `vng --dump`)
qemu_args += "-s -qmp tcp:localhost:3636,server,nowait "
if qemu_args != "":
self.virtme_param["qemu_opts"] = "--qemu-opts " + qemu_args
else:
Expand Down Expand Up @@ -1032,11 +1037,6 @@ def run(self, args):

def dump(self, args):
"""Generate or analyze a crash memory dump."""
if not os.path.isfile("vmlinux"):
arg_fail(
"vmlinux not found, try to recompile the kernel with "
+ "--build-host-vmlinux (if --build-host was used)"
)
# Use QMP to generate a memory dump
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 3636))
Expand All @@ -1055,7 +1055,7 @@ def dump(self, args):
with tempfile.NamedTemporaryFile(delete=dump_file is None) as tmp:
msg = (
'{"execute":"dump-guest-memory",'
'"arguments":{"paging":false,'
'"arguments":{"paging":true,'
'"protocol":"file:' + tmp.name + '"}}'
"\r"
)
Expand Down

0 comments on commit e77655a

Please sign in to comment.