diff options
Diffstat (limited to 'scripts/gdb/linux')
| -rw-r--r-- | scripts/gdb/linux/dmesg.py | 147 | ||||
| -rw-r--r-- | scripts/gdb/linux/proc.py | 15 | ||||
| -rw-r--r-- | scripts/gdb/linux/tasks.py | 9 | ||||
| -rw-r--r-- | scripts/gdb/linux/utils.py | 7 | 
4 files changed, 129 insertions, 49 deletions
| diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py index 2fa7bb83885f..a92c55bd8de5 100644 --- a/scripts/gdb/linux/dmesg.py +++ b/scripts/gdb/linux/dmesg.py @@ -16,8 +16,13 @@ import sys  from linux import utils -printk_log_type = utils.CachedType("struct printk_log") - +printk_info_type = utils.CachedType("struct printk_info") +prb_data_blk_lpos_type = utils.CachedType("struct prb_data_blk_lpos") +prb_desc_type = utils.CachedType("struct prb_desc") +prb_desc_ring_type = utils.CachedType("struct prb_desc_ring") +prb_data_ring_type = utils.CachedType("struct prb_data_ring") +printk_ringbuffer_type = utils.CachedType("struct printk_ringbuffer") +atomic_long_type = utils.CachedType("atomic_long_t")  class LxDmesg(gdb.Command):      """Print Linux kernel log buffer.""" @@ -26,44 +31,110 @@ class LxDmesg(gdb.Command):          super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA)      def invoke(self, arg, from_tty): -        log_buf_addr = int(str(gdb.parse_and_eval( -            "(void *)'printk.c'::log_buf")).split()[0], 16) -        log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx")) -        log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx")) -        log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len")) -          inf = gdb.inferiors()[0] -        start = log_buf_addr + log_first_idx -        if log_first_idx < log_next_idx: -            log_buf_2nd_half = -1 -            length = log_next_idx - log_first_idx -            log_buf = utils.read_memoryview(inf, start, length).tobytes() -        else: -            log_buf_2nd_half = log_buf_len - log_first_idx -            a = utils.read_memoryview(inf, start, log_buf_2nd_half) -            b = utils.read_memoryview(inf, log_buf_addr, log_next_idx) -            log_buf = a.tobytes() + b.tobytes() - -        length_offset = printk_log_type.get_type()['len'].bitpos // 8 -        text_len_offset = printk_log_type.get_type()['text_len'].bitpos // 8 -        time_stamp_offset = printk_log_type.get_type()['ts_nsec'].bitpos // 8 -        text_offset = printk_log_type.get_type().sizeof - -        pos = 0 -        while pos < log_buf.__len__(): -            length = utils.read_u16(log_buf, pos + length_offset) -            if length == 0: -                if log_buf_2nd_half == -1: -                    gdb.write("Corrupted log buffer!\n") + +        # read in prb structure +        prb_addr = int(str(gdb.parse_and_eval("(void *)'printk.c'::prb")).split()[0], 16) +        sz = printk_ringbuffer_type.get_type().sizeof +        prb = utils.read_memoryview(inf, prb_addr, sz).tobytes() + +        # read in descriptor ring structure +        off = printk_ringbuffer_type.get_type()['desc_ring'].bitpos // 8 +        addr = prb_addr + off +        sz = prb_desc_ring_type.get_type().sizeof +        desc_ring = utils.read_memoryview(inf, addr, sz).tobytes() + +        # read in descriptor array +        off = prb_desc_ring_type.get_type()['count_bits'].bitpos // 8 +        desc_ring_count = 1 << utils.read_u32(desc_ring, off) +        desc_sz = prb_desc_type.get_type().sizeof +        off = prb_desc_ring_type.get_type()['descs'].bitpos // 8 +        addr = utils.read_ulong(desc_ring, off) +        descs = utils.read_memoryview(inf, addr, desc_sz * desc_ring_count).tobytes() + +        # read in info array +        info_sz = printk_info_type.get_type().sizeof +        off = prb_desc_ring_type.get_type()['infos'].bitpos // 8 +        addr = utils.read_ulong(desc_ring, off) +        infos = utils.read_memoryview(inf, addr, info_sz * desc_ring_count).tobytes() + +        # read in text data ring structure +        off = printk_ringbuffer_type.get_type()['text_data_ring'].bitpos // 8 +        addr = prb_addr + off +        sz = prb_data_ring_type.get_type().sizeof +        text_data_ring = utils.read_memoryview(inf, addr, sz).tobytes() + +        # read in text data +        off = prb_data_ring_type.get_type()['size_bits'].bitpos // 8 +        text_data_sz = 1 << utils.read_u32(text_data_ring, off) +        off = prb_data_ring_type.get_type()['data'].bitpos // 8 +        addr = utils.read_ulong(text_data_ring, off) +        text_data = utils.read_memoryview(inf, addr, text_data_sz).tobytes() + +        counter_off = atomic_long_type.get_type()['counter'].bitpos // 8 + +        sv_off = prb_desc_type.get_type()['state_var'].bitpos // 8 + +        off = prb_desc_type.get_type()['text_blk_lpos'].bitpos // 8 +        begin_off = off + (prb_data_blk_lpos_type.get_type()['begin'].bitpos // 8) +        next_off = off + (prb_data_blk_lpos_type.get_type()['next'].bitpos // 8) + +        ts_off = printk_info_type.get_type()['ts_nsec'].bitpos // 8 +        len_off = printk_info_type.get_type()['text_len'].bitpos // 8 + +        # definitions from kernel/printk/printk_ringbuffer.h +        desc_committed = 1 +        desc_finalized = 2 +        desc_sv_bits = utils.get_long_type().sizeof * 8 +        desc_flags_shift = desc_sv_bits - 2 +        desc_flags_mask = 3 << desc_flags_shift +        desc_id_mask = ~desc_flags_mask + +        # read in tail and head descriptor ids +        off = prb_desc_ring_type.get_type()['tail_id'].bitpos // 8 +        tail_id = utils.read_u64(desc_ring, off + counter_off) +        off = prb_desc_ring_type.get_type()['head_id'].bitpos // 8 +        head_id = utils.read_u64(desc_ring, off + counter_off) + +        did = tail_id +        while True: +            ind = did % desc_ring_count +            desc_off = desc_sz * ind +            info_off = info_sz * ind + +            # skip non-committed record +            state = 3 & (utils.read_u64(descs, desc_off + sv_off + +                                        counter_off) >> desc_flags_shift) +            if state != desc_committed and state != desc_finalized: +                if did == head_id:                      break -                pos = log_buf_2nd_half +                did = (did + 1) & desc_id_mask                  continue -            text_len = utils.read_u16(log_buf, pos + text_len_offset) -            text_start = pos + text_offset -            text = log_buf[text_start:text_start + text_len].decode( -                encoding='utf8', errors='replace') -            time_stamp = utils.read_u64(log_buf, pos + time_stamp_offset) +            begin = utils.read_ulong(descs, desc_off + begin_off) % text_data_sz +            end = utils.read_ulong(descs, desc_off + next_off) % text_data_sz + +            # handle data-less record +            if begin & 1 == 1: +                text = "" +            else: +                # handle wrapping data block +                if begin > end: +                    begin = 0 + +                # skip over descriptor id +                text_start = begin + utils.get_long_type().sizeof + +                text_len = utils.read_u16(infos, info_off + len_off) + +                # handle truncated message +                if end - text_start < text_len: +                    text_len = end - text_start + +                text = text_data[text_start:text_start + text_len].decode( +                    encoding='utf8', errors='replace') + +            time_stamp = utils.read_u64(infos, info_off + ts_off)              for line in text.splitlines():                  msg = u"[{time:12.6f}] {line}\n".format( @@ -75,7 +146,9 @@ class LxDmesg(gdb.Command):                      msg = msg.encode(encoding='utf8', errors='replace')                  gdb.write(msg) -            pos += length +            if did == head_id: +                break +            did = (did + 1) & desc_id_mask  LxDmesg() diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py index 6a56bba233a9..09cd871925a5 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py @@ -167,6 +167,9 @@ values of that process namespace"""          if not namespace:              raise gdb.GdbError("No namespace for current process") +        gdb.write("{:^18} {:^15} {:>9} {} {} options\n".format( +                  "mount", "super_block", "devname", "pathname", "fstype")) +          for vfs in lists.list_for_each_entry(namespace['list'],                                               mount_ptr_type, "mnt_list"):              devname = vfs['mnt_devname'].string() @@ -190,14 +193,10 @@ values of that process namespace"""              m_flags = int(vfs['mnt']['mnt_flags'])              rd = "ro" if (s_flags & constants.LX_SB_RDONLY) else "rw" -            gdb.write( -                "{} {} {} {}{}{} 0 0\n" -                .format(devname, -                        pathname, -                        fstype, -                        rd, -                        info_opts(FS_INFO, s_flags), -                        info_opts(MNT_INFO, m_flags))) +            gdb.write("{} {} {} {} {} {}{}{} 0 0\n".format( +                      vfs.format_string(), superblock.format_string(), devname, +                      pathname, fstype, rd, info_opts(FS_INFO, s_flags), +                      info_opts(MNT_INFO, m_flags)))  LxMounts() diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py index 0301dc1e0138..17ec19e9b5bf 100644 --- a/scripts/gdb/linux/tasks.py +++ b/scripts/gdb/linux/tasks.py @@ -73,11 +73,12 @@ class LxPs(gdb.Command):          super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA)      def invoke(self, arg, from_tty): +        gdb.write("{:>10} {:>12} {:>7}\n".format("TASK", "PID", "COMM"))          for task in task_lists(): -            gdb.write("{address} {pid} {comm}\n".format( -                address=task, -                pid=task["pid"], -                comm=task["comm"].string())) +            gdb.write("{} {:^5} {}\n".format( +                task.format_string().split()[0], +                task["pid"].format_string(), +                task["comm"].string()))  LxPs() diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py index ea94221dbd39..ff7c1799d588 100644 --- a/scripts/gdb/linux/utils.py +++ b/scripts/gdb/linux/utils.py @@ -123,6 +123,13 @@ def read_u64(buffer, offset):          return read_u32(buffer, offset + 4) + (read_u32(buffer, offset) << 32) +def read_ulong(buffer, offset): +    if get_long_type().sizeof == 8: +        return read_u64(buffer, offset) +    else: +        return read_u32(buffer, offset) + +  target_arch = None | 
