|
| 1 | +0.0.33 (Released October 30th, 2025) |
| 2 | +==================================== |
| 3 | + |
| 4 | +These are some of the highlights of drgn 0.0.33. See the `GitHub release |
| 5 | +<https://github.com/osandov/drgn/releases/tag/v0.0.33>`_ for the full release |
| 6 | +notes, including more improvements and bug fixes. |
| 7 | + |
| 8 | +.. highlight:: pycon |
| 9 | +.. program:: drgn |
| 10 | + |
| 11 | +Lots of New Helpers |
| 12 | +------------------- |
| 13 | + |
| 14 | +This release adds over 80 new helpers! The majority are for the Linux kernel |
| 15 | +memory management subsystem: |
| 16 | + |
| 17 | +- :func:`~drgn.helpers.common.memory.identify_address_all()` |
| 18 | +- :func:`~drgn.helpers.linux.block.nr_blockdev_pages()` |
| 19 | +- :func:`~drgn.helpers.linux.hugetlb.for_each_hstate()` |
| 20 | +- :func:`~drgn.helpers.linux.hugetlb.huge_page_size()` |
| 21 | +- :func:`~drgn.helpers.linux.hugetlb.hugetlb_total_pages()` |
| 22 | +- :func:`~drgn.helpers.linux.hugetlb.hugetlb_total_usage()` |
| 23 | +- :func:`~drgn.helpers.linux.mm.decode_memory_block_state()` |
| 24 | +- :func:`~drgn.helpers.linux.mm.decode_page_flags_value()` |
| 25 | +- :func:`~drgn.helpers.linux.mm.for_each_memory_block()` |
| 26 | +- :func:`~drgn.helpers.linux.mm.for_each_valid_page_range()` |
| 27 | +- :func:`~drgn.helpers.linux.mm.for_each_valid_pfn_and_page()` |
| 28 | +- :func:`~drgn.helpers.linux.mm.memory_block_size_bytes()` |
| 29 | +- :func:`~drgn.helpers.linux.mm.page_flags()` |
| 30 | +- :func:`~drgn.helpers.linux.mm.page_index()` |
| 31 | +- :func:`~drgn.helpers.linux.mm.task_rss()` |
| 32 | +- :func:`~drgn.helpers.linux.mm.vm_commit_limit()` |
| 33 | +- :func:`~drgn.helpers.linux.mm.vm_memory_committed()` |
| 34 | +- :func:`~drgn.helpers.linux.mmzone.NODE_DATA()` |
| 35 | +- :func:`~drgn.helpers.linux.mmzone.decode_section_flags()` |
| 36 | +- :func:`~drgn.helpers.linux.mmzone.early_section_nr()` |
| 37 | +- :func:`~drgn.helpers.linux.mmzone.early_section()` |
| 38 | +- :func:`~drgn.helpers.linux.mmzone.for_each_online_pgdat()` |
| 39 | +- :func:`~drgn.helpers.linux.mmzone.for_each_present_section()` |
| 40 | +- :func:`~drgn.helpers.linux.mmzone.high_wmark_pages()` |
| 41 | +- :func:`~drgn.helpers.linux.mmzone.low_wmark_pages()` |
| 42 | +- :func:`~drgn.helpers.linux.mmzone.min_wmark_pages()` |
| 43 | +- :func:`~drgn.helpers.linux.mmzone.nr_to_section()` |
| 44 | +- :func:`~drgn.helpers.linux.mmzone.online_section_nr()` |
| 45 | +- :func:`~drgn.helpers.linux.mmzone.online_section()` |
| 46 | +- :func:`~drgn.helpers.linux.mmzone.pfn_to_section_nr()` |
| 47 | +- :func:`~drgn.helpers.linux.mmzone.pfn_to_section()` |
| 48 | +- :func:`~drgn.helpers.linux.mmzone.present_section_nr()` |
| 49 | +- :func:`~drgn.helpers.linux.mmzone.present_section()` |
| 50 | +- :func:`~drgn.helpers.linux.mmzone.section_decode_mem_map()` |
| 51 | +- :func:`~drgn.helpers.linux.mmzone.section_mem_map_addr()` |
| 52 | +- :func:`~drgn.helpers.linux.mmzone.section_nr_to_pfn()` |
| 53 | +- :func:`~drgn.helpers.linux.mmzone.valid_section_nr()` |
| 54 | +- :func:`~drgn.helpers.linux.mmzone.valid_section()` |
| 55 | +- :func:`~drgn.helpers.linux.mmzone.wmark_pages()` |
| 56 | +- :func:`~drgn.helpers.linux.slab.slab_cache_objects_per_slab()` |
| 57 | +- :func:`~drgn.helpers.linux.slab.slab_cache_order()` |
| 58 | +- :func:`~drgn.helpers.linux.slab.slab_cache_pages_per_slab()` |
| 59 | +- :func:`~drgn.helpers.linux.slab.slab_cache_usage()` |
| 60 | +- :func:`~drgn.helpers.linux.slab.slab_total_usage()` |
| 61 | +- :func:`~drgn.helpers.linux.swap.for_each_swap_info()` |
| 62 | +- :func:`~drgn.helpers.linux.swap.swap_file_path()` |
| 63 | +- :func:`~drgn.helpers.linux.swap.swap_is_file()` |
| 64 | +- :func:`~drgn.helpers.linux.swap.swap_total_usage()` |
| 65 | +- :func:`~drgn.helpers.linux.swap.swap_usage_in_pages()` |
| 66 | +- :func:`~drgn.helpers.linux.swap.total_swapcache_pages()` |
| 67 | +- :func:`~drgn.helpers.linux.vmstat.global_node_page_state()` |
| 68 | +- :func:`~drgn.helpers.linux.vmstat.global_numa_event_state()` |
| 69 | +- :func:`~drgn.helpers.linux.vmstat.global_vm_event_state()` |
| 70 | +- :func:`~drgn.helpers.linux.vmstat.global_zone_page_state()` |
| 71 | +- :func:`~drgn.helpers.linux.vmstat.nr_free_pages()` |
| 72 | +- :func:`~drgn.helpers.linux.vmstat.zone_page_state()` |
| 73 | + |
| 74 | +But there are many others for devices, the CPU scheduler, and more: |
| 75 | + |
| 76 | +- :func:`~drgn.helpers.common.format.double_quote_ascii_string()` |
| 77 | +- :func:`~drgn.helpers.common.type.typeof_member()` |
| 78 | +- :func:`~drgn.helpers.linux.device.bus_for_each_dev()` |
| 79 | +- :func:`~drgn.helpers.linux.device.bus_to_subsys()` |
| 80 | +- :func:`~drgn.helpers.linux.device.class_for_each_device()` |
| 81 | +- :func:`~drgn.helpers.linux.device.class_to_subsys()` |
| 82 | +- :func:`~drgn.helpers.linux.device.dev_name()` |
| 83 | +- :func:`~drgn.helpers.linux.fs.super_block_for_each_mount()` |
| 84 | +- :func:`~drgn.helpers.linux.kallsyms.module_kallsyms()` |
| 85 | +- :func:`~drgn.helpers.linux.kernfs.kernfs_children()` |
| 86 | +- :func:`~drgn.helpers.linux.list.validate_list_count_nodes()` |
| 87 | +- :func:`~drgn.helpers.linux.module.module_taints()` |
| 88 | +- :func:`~drgn.helpers.linux.nodemask.nr_node_ids()` |
| 89 | +- :func:`~drgn.helpers.linux.panic.panic_message()` |
| 90 | +- :func:`~drgn.helpers.linux.panic.panic_task()` |
| 91 | +- :func:`~drgn.helpers.linux.panic.tainted()` |
| 92 | +- :func:`~drgn.helpers.linux.percpu.percpu_counter_sum_positive()` |
| 93 | +- :func:`~drgn.helpers.linux.pid.for_each_task_in_group()` |
| 94 | +- :func:`~drgn.helpers.linux.rbtree.rbtree_preorder_for_each_entry()` |
| 95 | +- :func:`~drgn.helpers.linux.rbtree.rbtree_preorder_for_each()` |
| 96 | +- :func:`~drgn.helpers.linux.sched.cpu_rq()` |
| 97 | +- :func:`~drgn.helpers.linux.sched.get_task_state()` |
| 98 | +- :func:`~drgn.helpers.linux.sched.task_on_cpu()` |
| 99 | +- :func:`~drgn.helpers.linux.sched.task_rq()` |
| 100 | +- :func:`~drgn.helpers.linux.sched.task_since_last_arrival_ns()` |
| 101 | +- :func:`~drgn.helpers.experimental.kmodify.set_bit()` |
| 102 | +- :func:`~drgn.helpers.experimental.kmodify.clear_bit()` |
| 103 | + |
| 104 | +Address Identification Improvements |
| 105 | +----------------------------------- |
| 106 | + |
| 107 | +:func:`~drgn.helpers.common.memory.identify_address()` can now identify |
| 108 | +addresses from the kernel memory map (i.e., addresses in a ``struct page``) and |
| 109 | +addresses in a ``struct task_struct``:: |
| 110 | + |
| 111 | + >>> identify_address(pfn_to_page(0)) |
| 112 | + 'page: pfn 0' |
| 113 | + >>> identify_address(find_task(4)) |
| 114 | + 'task: 4 (kworker/R-rcu_g)' |
| 115 | + |
| 116 | +The new :func:`~drgn.helpers.common.memory.identify_address_all()` helper |
| 117 | +provides a programmatic interface for identifying addresses: |
| 118 | + |
| 119 | + |
| 120 | + >>> for identity in identify_address_all(find_task(4)): |
| 121 | + ... print(repr(identity)) |
| 122 | + ... |
| 123 | + IdentifiedTaskStruct(address=18446622477834301568, task=Object(prog, 'struct task_struct *', value=0xffff9168c10cb080)) |
| 124 | + IdentifiedSlabObject(address=18446622477834301568, slab_object_info=SlabObjectInfo(slab_cache=Object(prog, 'struct kmem_cache *', value=0xffff9168c0206c00), slab=Object(prog, 'struct slab *', value=0xffffd26b04043200), address=0xffff9168c10cb080, allocated=True)) |
| 125 | + |
| 126 | +Array Slices |
| 127 | +------------ |
| 128 | + |
| 129 | +Array and pointer objects can now be sliced. This is especially useful for |
| 130 | +converting a flexible array member or pointer to a fixed-length array:: |
| 131 | + |
| 132 | + >>> poll_list |
| 133 | + *(struct poll_list *)0xffffad92459a39a0 = { |
| 134 | + .next = (struct poll_list *)0x0, |
| 135 | + .len = (unsigned int)2, |
| 136 | + .entries = (struct pollfd []){}, |
| 137 | + } |
| 138 | + >>> poll_list.entries[:poll_list.len] |
| 139 | + (struct pollfd [2]){ |
| 140 | + { |
| 141 | + .fd = (int)4, |
| 142 | + .events = (short)1, |
| 143 | + .revents = (short)0, |
| 144 | + }, |
| 145 | + { |
| 146 | + .fd = (int)9, |
| 147 | + .events = (short)1, |
| 148 | + .revents = (short)0, |
| 149 | + }, |
| 150 | + } |
| 151 | + |
| 152 | +More Reliable Interrupt Stack Traces |
| 153 | +------------------------------------ |
| 154 | + |
| 155 | +Stephen Brennan improved stack tracing on x86-64 kernels that use the frame |
| 156 | +pointer unwinder (Ubuntu kernels, for example) and AArch64 so that it reliably |
| 157 | +unwinds through interrupts. |
| 158 | + |
| 159 | +Kmodify Bit Field Fix |
| 160 | +--------------------- |
| 161 | + |
| 162 | +:func:`drgn.helpers.experimental.kmodify.write_object()` was found to have a |
| 163 | +major bug when writing to bit fields. It didn't take the field's bit offset or |
| 164 | +bit size into account, meaning that it wrote to the wrong bits and overwrote |
| 165 | +additional memory, too. |
| 166 | + |
| 167 | +This release fixes it to handle bit fields of size 1 (atomically) and reject |
| 168 | +larger bit fields. Support for larger bit fields can be added if requested. |
| 169 | + |
| 170 | +Linux 6.17 and 6.18 Support |
| 171 | +--------------------------- |
| 172 | + |
| 173 | +A change in Linux 6.17 broke drgn's timekeeping helpers. This error is fixed in |
| 174 | +this release:: |
| 175 | + |
| 176 | + KeyError: 'tk_core' |
| 177 | + |
| 178 | +A change in Linux 6.17 broke ``tools/fsrefs.py --super-block-on-block-device`` |
| 179 | +on Btrfs. This error is fixed in this release:: |
| 180 | + |
| 181 | + no filesystem found on /dev/... |
| 182 | + |
| 183 | +A change in Linux 6.18 broke :func:`~drgn.helpers.linux.fs.d_path()` when |
| 184 | +passing only a ``struct dentry *``. This error is fixed in this release:: |
| 185 | + |
| 186 | + AttributeError: '_drgn.Object' object has no attribute 'next' |
| 187 | + |
| 188 | +A change in Linux 6.18 broke |
| 189 | +:func:`~drgn.helpers.linux.net.get_net_ns_by_inode()`. This error is fixed in |
| 190 | +this release:: |
| 191 | + |
| 192 | + AttributeError: 'struct proc_ns_operations' has no member 'type'. Did you mean: 'type_'? |
| 193 | + |
| 194 | +No More Python 3.6 & 3.7 Support |
| 195 | +-------------------------------- |
| 196 | + |
| 197 | +As `previously announced <https://github.com/osandov/drgn/issues/467>`_, this |
| 198 | +release dropped support for Python 3.6 and 3.7. |
0 commit comments