Struct udmp_parser::Thread
source · pub struct Thread<'a> {
pub id: u32,
pub suspend_count: u32,
pub priority_class: u32,
pub priority: u32,
pub teb: u64,
/* private fields */
}
Expand description
A thread that was running when the dump was generated.
Fields§
§id: u32
The thread ID.
suspend_count: u32
The suspend count counter cf Freezing and Suspending Threads.
priority_class: u32
The priority class cf Priority Class.
priority: u32
Thread priority cf Priority level.
teb: u64
The thread environment block address.
Implementations§
source§impl<'a> Thread<'a>
impl<'a> Thread<'a>
sourcepub fn context(&self) -> &ThreadContext<'_>
pub fn context(&self) -> &ThreadContext<'_>
Get a reference to the ThreadContext
.
Examples found in repository?
examples/parser.rs (line 252)
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
fn main() -> Result<(), String> {
// If we don't have any arguments, display the help.
if env::args().len() == 1 {
help();
return Ok(());
}
// Parse the command line arguments.
let cli = parse_args()?;
// Let's try to parse the dump file specified by the user.
let dump = UserDumpParser::new(cli.dump_path).map_err(|e| e.to_string())?;
// Do we want to display modules?
if cli.show_mods || cli.show_all {
println!("Loaded modules:");
// Iterate through the module and display their base address and path.
for (base, module) in dump.modules() {
println!("{:016x}: {}", base, module.path.display());
}
}
// Do we want the memory map?
if cli.show_memmap || cli.show_all {
println!("Memory map:");
// Iterate over the memory blocks.
for block in dump.mem_blocks().values() {
// Grab the string representation about its state, type, protection.
let state = block.state_as_str();
let type_ = block.type_as_str();
let protect = block.protect_as_str();
// Print it all out.
print!(
"{:016x} {:016x} {:016x} {:11} {:11} {:22}",
block.range.start,
block.range.end,
block.len(),
type_,
state,
protect
);
// Do we have a module that exists at this address?
let module = dump.get_module(block.range.start);
// If we do, then display its name / path.
if let Some(module) = module {
print!(
" [{}; \"{}\"]",
module.file_name().unwrap(),
module.path.display()
);
}
// Do we have data with this block? If so display the first few
// bytes.
if block.data.len() >= 4 {
print!(
" {:02x} {:02x} {:02x} {:02x}...",
block.data[0], block.data[1], block.data[2], block.data[3]
);
}
println!();
}
}
// Do we want threads?
if cli.show_threads || cli.show_all {
println!("Threads:");
// Grab the foreground tid.
let foreground_tid = dump.foreground_tid;
// Iterate through all the threads.
for (tid, thread) in dump.threads() {
// If the user specified a pid..
if let Some(wanted_tid) = cli.thread {
// .. skip an threads that don't match what the user wants..
if *tid != wanted_tid {
continue;
}
// Otherwise we keep going.
}
// If the user only wants the main thread, and we haven't found it,
// skip this thread until we find it.
if cli.show_foreground_thread
&& *tid != foreground_tid.expect("no foreground thread id in dump")
{
continue;
}
// Print out the thread info.
println!("TID {}, TEB {:016x}", tid, thread.teb);
println!("Context:");
println!("{}", thread.context());
}
}
// Do we want to dump memory?
if let Some(address) = cli.address {
println!("Memory:");
// Try to find a block that contains `address`.
let block = dump.get_mem_block(address);
// If we have one..
if let Some(block) = block {
// .. and it has data, dump it..
if let Some(data) = block.data_from(address) {
println!("{:016x} -> {:016x}", address, block.end_addr());
hexdump(address, data.iter().take(0x1_00).copied());
}
// .. otherwise, inform the user..
else {
println!(
"The memory at {:016x} (from block {:016x} -> {:016x}) has no backing data",
address, block.range.start, block.range.end
);
}
}
// .. otherwise, inform he user.
else {
println!("No memory block were found for {:016x}", address);
}
}
// All right, enough for today.
Ok(())
}
Trait Implementations§
Auto Trait Implementations§
impl<'a> Freeze for Thread<'a>
impl<'a> RefUnwindSafe for Thread<'a>
impl<'a> Send for Thread<'a>
impl<'a> Sync for Thread<'a>
impl<'a> Unpin for Thread<'a>
impl<'a> UnwindSafe for Thread<'a>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more