2 # gdb helper commands and functions for Linux kernel debugging
4 # Kernel proc information reader
6 # Copyright (c) 2016 Linaro Ltd
9 # Kieran Bingham <kieran.bingham@linaro.org>
11 # This work is licensed under the terms of the GNU GPL version 2.
15 from linux
import constants
16 from linux
import utils
17 from linux
import tasks
18 from linux
import lists
21 class LxCmdLine(gdb
.Command
):
22 """ Report the Linux Commandline used in the current kernel.
23 Equivalent to cat /proc/cmdline on a running target"""
26 super(LxCmdLine
, self
).__init
__("lx-cmdline", gdb
.COMMAND_DATA
)
28 def invoke(self
, arg
, from_tty
):
29 gdb
.write(gdb
.parse_and_eval("saved_command_line").string() + "\n")
34 class LxVersion(gdb
.Command
):
35 """ Report the Linux Version of the current kernel.
36 Equivalent to cat /proc/version on a running target"""
39 super(LxVersion
, self
).__init
__("lx-version", gdb
.COMMAND_DATA
)
41 def invoke(self
, arg
, from_tty
):
42 # linux_banner should contain a newline
43 gdb
.write(gdb
.parse_and_eval("linux_banner").string())
48 # Resource Structure Printers
52 def get_resources(resource
, depth
):
56 child
= resource
['child']
58 for res
, deep
in get_resources(child
, depth
+ 1):
61 resource
= resource
['sibling']
64 def show_lx_resources(resource_str
):
65 resource
= gdb
.parse_and_eval(resource_str
)
66 width
= 4 if resource
['end'] < 0x10000 else 8
67 # Iterate straight to the first child
68 for res
, depth
in get_resources(resource
['child'], 0):
69 start
= int(res
['start'])
71 gdb
.write(" " * depth
* 2 +
72 "{0:0{1}x}-".format(start
, width
) +
73 "{0:0{1}x} : ".format(end
, width
) +
74 res
['name'].string() + "\n")
77 class LxIOMem(gdb
.Command
):
78 """Identify the IO memory resource locations defined by the kernel
80 Equivalent to cat /proc/iomem on a running target"""
83 super(LxIOMem
, self
).__init
__("lx-iomem", gdb
.COMMAND_DATA
)
85 def invoke(self
, arg
, from_tty
):
86 return show_lx_resources("iomem_resource")
91 class LxIOPorts(gdb
.Command
):
92 """Identify the IO port resource locations defined by the kernel
94 Equivalent to cat /proc/ioports on a running target"""
97 super(LxIOPorts
, self
).__init
__("lx-ioports", gdb
.COMMAND_DATA
)
99 def invoke(self
, arg
, from_tty
):
100 return show_lx_resources("ioport_resource")
105 # Mount namespace viewer
108 def info_opts(lst
, opt
):
110 for key
, string
in lst
.items():
116 FS_INFO
= {constants
.LX_MS_SYNCHRONOUS
: ",sync",
117 constants
.LX_MS_MANDLOCK
: ",mand",
118 constants
.LX_MS_DIRSYNC
: ",dirsync",
119 constants
.LX_MS_NOATIME
: ",noatime",
120 constants
.LX_MS_NODIRATIME
: ",nodiratime"}
122 MNT_INFO
= {constants
.LX_MNT_NOSUID
: ",nosuid",
123 constants
.LX_MNT_NODEV
: ",nodev",
124 constants
.LX_MNT_NOEXEC
: ",noexec",
125 constants
.LX_MNT_NOATIME
: ",noatime",
126 constants
.LX_MNT_NODIRATIME
: ",nodiratime",
127 constants
.LX_MNT_RELATIME
: ",relatime"}
129 mount_type
= utils
.CachedType("struct mount")
130 mount_ptr_type
= mount_type
.get_type().pointer()
133 class LxMounts(gdb
.Command
):
134 """Report the VFS mounts of the current process namespace.
136 Equivalent to cat /proc/mounts on a running target
137 An integer value can be supplied to display the mount
138 values of that process namespace"""
141 super(LxMounts
, self
).__init
__("lx-mounts", gdb
.COMMAND_DATA
)
143 # Equivalent to proc_namespace.c:show_vfsmnt
144 # However, that has the ability to call into s_op functions
145 # whereas we cannot and must make do with the information we can obtain.
146 def invoke(self
, arg
, from_tty
):
147 argv
= gdb
.string_to_argv(arg
)
152 raise gdb
.GdbError("Provide a PID as integer value")
156 task
= tasks
.get_task_by_pid(pid
)
158 raise gdb
.GdbError("Couldn't find a process with PID {}"
161 namespace
= task
['nsproxy']['mnt_ns']
163 raise gdb
.GdbError("No namespace for current process")
165 for vfs
in lists
.list_for_each_entry(namespace
['list'],
166 mount_ptr_type
, "mnt_list"):
167 devname
= vfs
['mnt_devname'].string()
168 devname
= devname
if devname
else "none"
173 mntpoint
= parent
['mnt_mountpoint']
174 pathname
= utils
.dentry_name(mntpoint
) + pathname
175 if (parent
== parent
['mnt_parent']):
177 parent
= parent
['mnt_parent']
182 superblock
= vfs
['mnt']['mnt_sb']
183 fstype
= superblock
['s_type']['name'].string()
184 s_flags
= int(superblock
['s_flags'])
185 m_flags
= int(vfs
['mnt']['mnt_flags'])
186 rd
= "ro" if (s_flags
& constants
.LX_MS_RDONLY
) else "rw"
189 "{} {} {} {}{}{} 0 0\n"
194 info_opts(FS_INFO
, s_flags
),
195 info_opts(MNT_INFO
, m_flags
)))
This page took 0.037804 seconds and 6 git commands to generate.