diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 000000000..d8935585b --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,3 @@ +### Content + +This folder should only contain tools and utilities not essential to the compilation of SunriseOS, but which can help its debugging and development. diff --git a/scripts/gdb/README.md b/scripts/gdb/README.md new file mode 100644 index 000000000..d7ba4ea0c --- /dev/null +++ b/scripts/gdb/README.md @@ -0,0 +1,18 @@ +### Content + +This folder contains gdb scripts and configurations, to help you keep your sanity during debugging sessions. + +##### gdbinit + +This template gdbinit is provided as an example. + +You shouldn't use or modify it directly, but rather copy it to the root of this project, where it will be ignored by git and make any modifications you want there. +That way everyone can keep their own custom version without being harassed by git. + +For it to be used by gdb when you start it, make sure to add this line to your `~/.gdbinit`: + +```shell +$ cat ~/.gdbinit +#authorize running the .gdbinit in some folders +add-auto-load-safe-path /.gdbinit +``` diff --git a/scripts/gdb/break_userspace.py b/scripts/gdb/break_userspace.py new file mode 100644 index 000000000..75710afc8 --- /dev/null +++ b/scripts/gdb/break_userspace.py @@ -0,0 +1,46 @@ +import gdb + +class UserspaceBreakpoint(gdb.Breakpoint): + """Breakpoint breaking only in the right sunrise executable + +Breakpoint that breaks only if we're in the right userspace executable, since all .text are loaded at the same address. + +It uses the name found in the kernel current ProcessStruct and compares it with the module we're debugging to decide if it should break or not. + """ + def __init__(self, *args, **kwargs): + super(UserspaceBreakpoint, self).__init__(*args, **kwargs) + for objfile in gdb.objfiles(): + filename = objfile.filename.split("/")[-1] + if not filename.startswith("sunrise-kernel"): + self.proc_name = filename.split("sunrise-")[-1] + break + + + def stop (self): + cur_proc_name_expr = "(*sunrise_kernel::scheduler::CURRENT_THREAD.0.ptr.pointer).data.process.ptr.pointer.data.name.vec.buf.ptr.pointer" + cur_proc_name = gdb.parse_and_eval(cur_proc_name_expr).string() + if cur_proc_name == self.proc_name: + return True + return False + +class BreakUserspaceCommand(gdb.Command): + """Break only if in the right sunrise executable + +Creates a breakpoint that breaks only if we're in the right userspace executable, since all .text are loaded at the same address. + +It uses the name found in the kernel current ProcessStruct and compares it with the module we're debugging to decide if it should break or not. + +Usage: + break_userspace { args forwarded to break } + """ + def __init__(self): + super(BreakUserspaceCommand, self).__init__( + "break_userspace", + gdb.COMMAND_BREAKPOINTS, + gdb.COMPLETE_LOCATION, + False) + + def invoke(self, args, from_tty): + UserspaceBreakpoint(args) + +BreakUserspaceCommand() diff --git a/scripts/gdb/gdbinit b/scripts/gdb/gdbinit new file mode 100644 index 000000000..3d2c52f16 --- /dev/null +++ b/scripts/gdb/gdbinit @@ -0,0 +1,14 @@ +# Connect to the qemu stub through tcp. +# This should block until the compilation has ended and qemu has started, +# so it guarantees we are sourcing the up-to-date binaries afterward. +target remote :9090 + +# Add the kernel and all its symbols. +file isofiles/boot/sunrise-kernel + +# Add a userspace process and all its symbols. +# We specify the address at which the kernel loaded it. +add-symbol-file isofiles/boot/sunrise-shell 0x00400000 + +# Source sunrise scripts. +source scripts/gdb/break_userspace.py