~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/gdb/linux/cpus.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/gdb/linux/cpus.py (Version linux-6.12-rc7) and /scripts/gdb/linux/cpus.py (Version linux-4.19.323)


  1 #                                                   1 #
  2 # gdb helper commands and functions for Linux       2 # gdb helper commands and functions for Linux kernel debugging
  3 #                                                   3 #
  4 #  per-cpu tools                                    4 #  per-cpu tools
  5 #                                                   5 #
  6 # Copyright (c) Siemens AG, 2011-2013               6 # Copyright (c) Siemens AG, 2011-2013
  7 #                                                   7 #
  8 # Authors:                                          8 # Authors:
  9 #  Jan Kiszka <jan.kiszka@siemens.com>               9 #  Jan Kiszka <jan.kiszka@siemens.com>
 10 #                                                  10 #
 11 # This work is licensed under the terms of the     11 # This work is licensed under the terms of the GNU GPL version 2.
 12 #                                                  12 #
 13                                                    13 
 14 import gdb                                         14 import gdb
 15                                                    15 
 16 from linux import tasks, utils                     16 from linux import tasks, utils
 17                                                    17 
 18                                                    18 
 19 task_type = utils.CachedType("struct task_stru << 
 20                                                << 
 21                                                << 
 22 MAX_CPUS = 4096                                    19 MAX_CPUS = 4096
 23                                                    20 
 24                                                    21 
 25 def get_current_cpu():                             22 def get_current_cpu():
 26     if utils.get_gdbserver_type() == utils.GDB     23     if utils.get_gdbserver_type() == utils.GDBSERVER_QEMU:
 27         return gdb.selected_thread().num - 1       24         return gdb.selected_thread().num - 1
 28     elif utils.get_gdbserver_type() == utils.G     25     elif utils.get_gdbserver_type() == utils.GDBSERVER_KGDB:
 29         return gdb.parse_and_eval("kgdb_active !!  26         tid = gdb.selected_thread().ptid[2]
                                                   >>  27         if tid > (0x100000000 - MAX_CPUS - 2):
                                                   >>  28             return 0x100000000 - tid - 2
                                                   >>  29         else:
                                                   >>  30             return tasks.get_thread_info(tasks.get_task_by_pid(tid))['cpu']
 30     else:                                          31     else:
 31         raise gdb.GdbError("Sorry, obtaining t     32         raise gdb.GdbError("Sorry, obtaining the current CPU is not yet "
 32                            "supported with thi     33                            "supported with this gdb server.")
 33                                                    34 
 34                                                    35 
 35 def per_cpu(var_ptr, cpu):                         36 def per_cpu(var_ptr, cpu):
 36     if cpu == -1:                                  37     if cpu == -1:
 37         cpu = get_current_cpu()                    38         cpu = get_current_cpu()
 38     if utils.is_target_arch("sparc:v9"):           39     if utils.is_target_arch("sparc:v9"):
 39         offset = gdb.parse_and_eval(               40         offset = gdb.parse_and_eval(
 40             "trap_block[{0}].__per_cpu_base".f     41             "trap_block[{0}].__per_cpu_base".format(str(cpu)))
 41     else:                                          42     else:
 42         try:                                       43         try:
 43             offset = gdb.parse_and_eval(           44             offset = gdb.parse_and_eval(
 44                 "__per_cpu_offset[{0}]".format     45                 "__per_cpu_offset[{0}]".format(str(cpu)))
 45         except gdb.error:                          46         except gdb.error:
 46             # !CONFIG_SMP case                     47             # !CONFIG_SMP case
 47             offset = 0                             48             offset = 0
 48     pointer = var_ptr.cast(utils.get_long_type     49     pointer = var_ptr.cast(utils.get_long_type()) + offset
 49     return pointer.cast(var_ptr.type).derefere     50     return pointer.cast(var_ptr.type).dereference()
 50                                                    51 
 51                                                    52 
 52 cpu_mask = {}                                      53 cpu_mask = {}
 53                                                    54 
 54                                                    55 
 55 def cpu_mask_invalidate(event):                    56 def cpu_mask_invalidate(event):
 56     global cpu_mask                                57     global cpu_mask
 57     cpu_mask = {}                                  58     cpu_mask = {}
 58     gdb.events.stop.disconnect(cpu_mask_invali     59     gdb.events.stop.disconnect(cpu_mask_invalidate)
 59     if hasattr(gdb.events, 'new_objfile'):         60     if hasattr(gdb.events, 'new_objfile'):
 60         gdb.events.new_objfile.disconnect(cpu_     61         gdb.events.new_objfile.disconnect(cpu_mask_invalidate)
 61                                                    62 
 62                                                    63 
 63 def cpu_list(mask_name):                           64 def cpu_list(mask_name):
 64     global cpu_mask                                65     global cpu_mask
 65     mask = None                                    66     mask = None
 66     if mask_name in cpu_mask:                      67     if mask_name in cpu_mask:
 67         mask = cpu_mask[mask_name]                 68         mask = cpu_mask[mask_name]
 68     if mask is None:                               69     if mask is None:
 69         mask = gdb.parse_and_eval(mask_name +      70         mask = gdb.parse_and_eval(mask_name + ".bits")
 70         if hasattr(gdb, 'events'):                 71         if hasattr(gdb, 'events'):
 71             cpu_mask[mask_name] = mask             72             cpu_mask[mask_name] = mask
 72             gdb.events.stop.connect(cpu_mask_i     73             gdb.events.stop.connect(cpu_mask_invalidate)
 73             if hasattr(gdb.events, 'new_objfil     74             if hasattr(gdb.events, 'new_objfile'):
 74                 gdb.events.new_objfile.connect     75                 gdb.events.new_objfile.connect(cpu_mask_invalidate)
 75     bits_per_entry = mask[0].type.sizeof * 8       76     bits_per_entry = mask[0].type.sizeof * 8
 76     num_entries = mask.type.sizeof * 8 / bits_     77     num_entries = mask.type.sizeof * 8 / bits_per_entry
 77     entry = -1                                     78     entry = -1
 78     bits = 0                                       79     bits = 0
 79                                                    80 
 80     while True:                                    81     while True:
 81         while bits == 0:                           82         while bits == 0:
 82             entry += 1                             83             entry += 1
 83             if entry == num_entries:               84             if entry == num_entries:
 84                 return                             85                 return
 85             bits = mask[entry]                     86             bits = mask[entry]
 86             if bits != 0:                          87             if bits != 0:
 87                 bit = 0                            88                 bit = 0
 88                 break                              89                 break
 89                                                    90 
 90         while bits & 1 == 0:                       91         while bits & 1 == 0:
 91             bits >>= 1                             92             bits >>= 1
 92             bit += 1                               93             bit += 1
 93                                                    94 
 94         cpu = entry * bits_per_entry + bit         95         cpu = entry * bits_per_entry + bit
 95                                                    96 
 96         bits >>= 1                                 97         bits >>= 1
 97         bit += 1                                   98         bit += 1
 98                                                    99 
 99         yield int(cpu)                            100         yield int(cpu)
100                                                   101 
101                                                   102 
102 def each_online_cpu():                            103 def each_online_cpu():
103     for cpu in cpu_list("__cpu_online_mask"):     104     for cpu in cpu_list("__cpu_online_mask"):
104         yield cpu                                 105         yield cpu
105                                                   106 
106                                                   107 
107 def each_present_cpu():                           108 def each_present_cpu():
108     for cpu in cpu_list("__cpu_present_mask"):    109     for cpu in cpu_list("__cpu_present_mask"):
109         yield cpu                                 110         yield cpu
110                                                   111 
111                                                   112 
112 def each_possible_cpu():                          113 def each_possible_cpu():
113     for cpu in cpu_list("__cpu_possible_mask")    114     for cpu in cpu_list("__cpu_possible_mask"):
114         yield cpu                                 115         yield cpu
115                                                   116 
116                                                   117 
117 def each_active_cpu():                            118 def each_active_cpu():
118     for cpu in cpu_list("__cpu_active_mask"):     119     for cpu in cpu_list("__cpu_active_mask"):
119         yield cpu                                 120         yield cpu
120                                                   121 
121                                                   122 
122 class LxCpus(gdb.Command):                        123 class LxCpus(gdb.Command):
123     """List CPU status arrays                     124     """List CPU status arrays
124                                                   125 
125 Displays the known state of each CPU based on     126 Displays the known state of each CPU based on the kernel masks
126 and can help identify the state of hotplugged     127 and can help identify the state of hotplugged CPUs"""
127                                                   128 
128     def __init__(self):                           129     def __init__(self):
129         super(LxCpus, self).__init__("lx-cpus"    130         super(LxCpus, self).__init__("lx-cpus", gdb.COMMAND_DATA)
130                                                   131 
131     def invoke(self, arg, from_tty):              132     def invoke(self, arg, from_tty):
132         gdb.write("Possible CPUs : {}\n".forma    133         gdb.write("Possible CPUs : {}\n".format(list(each_possible_cpu())))
133         gdb.write("Present CPUs  : {}\n".forma    134         gdb.write("Present CPUs  : {}\n".format(list(each_present_cpu())))
134         gdb.write("Online CPUs   : {}\n".forma    135         gdb.write("Online CPUs   : {}\n".format(list(each_online_cpu())))
135         gdb.write("Active CPUs   : {}\n".forma    136         gdb.write("Active CPUs   : {}\n".format(list(each_active_cpu())))
136                                                   137 
137                                                << 
138 LxCpus()                                          138 LxCpus()
139                                                   139 
140                                                   140 
141 class PerCpu(gdb.Function):                       141 class PerCpu(gdb.Function):
142     """Return per-cpu variable.                   142     """Return per-cpu variable.
143                                                   143 
144 $lx_per_cpu("VAR"[, CPU]): Return the per-cpu     144 $lx_per_cpu("VAR"[, CPU]): Return the per-cpu variable called VAR for the
145 given CPU number. If CPU is omitted, the CPU o    145 given CPU number. If CPU is omitted, the CPU of the current context is used.
146 Note that VAR has to be quoted as string."""      146 Note that VAR has to be quoted as string."""
147                                                   147 
148     def __init__(self):                           148     def __init__(self):
149         super(PerCpu, self).__init__("lx_per_c    149         super(PerCpu, self).__init__("lx_per_cpu")
150                                                   150 
151     def invoke(self, var, cpu=-1):             !! 151     def invoke(self, var_name, cpu=-1):
152         return per_cpu(var.address, cpu)       !! 152         var_ptr = gdb.parse_and_eval("&" + var_name.string())
                                                   >> 153         return per_cpu(var_ptr, cpu)
153                                                   154 
154                                                   155 
155 PerCpu()                                          156 PerCpu()
156                                                   157 
157 def get_current_task(cpu):                     << 
158     task_ptr_type = task_type.get_type().point << 
159                                                << 
160     if utils.is_target_arch("x86"):            << 
161         if gdb.lookup_global_symbol("cpu_tasks << 
162             # This is a UML kernel, which stor << 
163             # differently than other x86 sub a << 
164             var_ptr = gdb.parse_and_eval("(str << 
165             return var_ptr.dereference()       << 
166         else:                                  << 
167             var_ptr = gdb.parse_and_eval("&pcp << 
168             return per_cpu(var_ptr, cpu).deref << 
169     elif utils.is_target_arch("aarch64"):      << 
170         current_task_addr = gdb.parse_and_eval << 
171         if (current_task_addr >> 63) != 0:     << 
172             current_task = current_task_addr.c << 
173             return current_task.dereference()  << 
174         else:                                  << 
175             raise gdb.GdbError("Sorry, obtaini << 
176                                "while running  << 
177     elif utils.is_target_arch("riscv"):        << 
178         current_tp = gdb.parse_and_eval("$tp") << 
179         scratch_reg = gdb.parse_and_eval("$ssc << 
180                                                << 
181         # by default tp points to current task << 
182         current_task = current_tp.cast(task_pt << 
183                                                << 
184         # scratch register is set 0 in trap ha << 
185         # When hart is in user mode, scratch r << 
186         # and tp is used by user mode. So when << 
187         # (negative address as ulong is larger << 
188         if (scratch_reg.cast(utils.get_ulong_t << 
189             current_task = scratch_reg.cast(ta << 
190                                                << 
191         return current_task.dereference()      << 
192     else:                                      << 
193         raise gdb.GdbError("Sorry, obtaining t << 
194                            "supported with thi << 
195                                                   158 
196 class LxCurrentFunc(gdb.Function):                159 class LxCurrentFunc(gdb.Function):
197     """Return current task.                       160     """Return current task.
198                                                   161 
199 $lx_current([CPU]): Return the per-cpu task va    162 $lx_current([CPU]): Return the per-cpu task variable for the given CPU
200 number. If CPU is omitted, the CPU of the curr    163 number. If CPU is omitted, the CPU of the current context is used."""
201                                                   164 
202     def __init__(self):                           165     def __init__(self):
203         super(LxCurrentFunc, self).__init__("l    166         super(LxCurrentFunc, self).__init__("lx_current")
204                                                   167 
205     def invoke(self, cpu=-1):                     168     def invoke(self, cpu=-1):
206         return get_current_task(cpu)           !! 169         var_ptr = gdb.parse_and_eval("&current_task")
                                                   >> 170         return per_cpu(var_ptr, cpu).dereference()
207                                                   171 
208                                                   172 
209 LxCurrentFunc()                                   173 LxCurrentFunc()
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php