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