You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Does minidump-writer support dumping stack without crash? #37
Sometimes there are bugs in the program that one thread may run into dead loop and burn cpu.
We can spawn watch-dog thread to monitor all thread and dump stack if dead-loop occur.
So it can be very helpful if minidump-writer supports dumping stack without crash.
For Linux the crash context is optional, but you are correct that it should also be optional for windows and mac as well. That being said, it's also fairly trivial to generate a crash context for Mac and Windows manually.
// Unsafe functionuse windows_sys::Win32::{System::{Diagnostics::Debug::{RtlCaptureContext,EXCEPTION_POINTERS,EXCEPTION_RECORD,},Threading::GetCurrentThreadId,},};letmut exception_record:EXCEPTION_RECORD = std::mem::zeroed();letmut exception_context = std::mem::MaybeUninit::uninit();// Get the CPU contextRtlCaptureContext(exception_context.as_mut_ptr());letmut exception_context = exception_context.assume_init();let exception_ptrs = EXCEPTION_POINTERS{ExceptionRecord:&mut exception_record,ContextRecord:&mut exception_context,};let exception_code = <a Windows windows_sys::Win32::Foundation::STATUS_* exception code>;
exception_record.ExceptionCode = exception_code;let cc = crash_context::CrashContext{exception_pointers:(&exception_ptrs as*constEXCEPTION_POINTERS).cast(),process_id: std::process::id(),thread_id:GetCurrentThreadId(),// or even better, the id of the thread that got stuck
exception_code,};
// Unsafe functionlet cc = crash_context::CrashContext{task: mach2::traps::mach_task_self(),thread: mach2::mach_init::mach_thread_self(),// preferably the id of the thread that is stuckhandler_thread: mach2::mach_init::mach_thread_self(),exception:None,// or optionally fill out the exception info};
Thanks @Jake-Shadle for the reply
For linux, there are two args that MinidumpWriter::new(process: Pid, blamed_thread: Pid)
How to fill with MinidumpWriter::new with args of process and blamed_thread ?
@Jake-Shadle
I use libc::gettid() and fail to build with error undefined reference to `gettid'
And I change to libc::syscall(libc::SYS_gettid) and build success
However, after cargo run it print error message:
No threads left to suspend out of 9
That is most likely because you need to the mark the process as dumpable with libc::syscall(libc::SYS_prctl, PR_SET_DUMPABLE, 1, 0, 0, 0) otherwise most/all ptrace operations will fail. You might also run into problems using minidumper in the same process, it was never designed for that so it has no protections against suspending the thread that is currently executing, the man page doesn't say anything AFAICT about special behavior for attaching to the currently executing thread, so I'm assuming it will actually send SIGSTOP to the thread and dead lock your program, so you could try adding logic to ignore stopping the thread if it is the same thread id as the current thread.
libc::syscall(libc::SYS_prctl, PR_SET_DUMPABLE, 1, 0, 0, 0) did not work and still "No threads left to suspend out of 9"
I give up and plan to dump in another process
Thank you very much @Jake-Shadle
Activity
simon-fu commentedon Jun 26, 2022
or in other words, how to make CrashContext without crashing for linux/macos/windows ?
Jake-Shadle commentedon Jun 30, 2022
For Linux the crash context is optional, but you are correct that it should also be optional for windows and mac as well. That being said, it's also fairly trivial to generate a crash context for Mac and Windows manually.
simon-fu commentedon Jul 8, 2022
Thanks @Jake-Shadle for the reply
For linux, there are two args that MinidumpWriter::new(process: Pid, blamed_thread: Pid)
How to fill with MinidumpWriter::new with args of process and blamed_thread ?
Jake-Shadle commentedon Jul 8, 2022
If you're dumping the same process you could use std::process:id() to get the process identifier, the thread identifier you either retrieve in the thread itself by calling
libc::gettid()or if you have aJoinHandleor similar you can get the thread id with https://doc.rust-lang.org/std/os/unix/thread/trait.JoinHandleExt.html#tymethod.as_pthread_tsimon-fu commentedon Jul 8, 2022
@Jake-Shadle
I use libc::gettid() and fail to build with error undefined reference to `gettid'
And I change to libc::syscall(libc::SYS_gettid) and build success
However, after cargo run it print error message:
No threads left to suspend out of 9
Jake-Shadle commentedon Jul 8, 2022
That is most likely because you need to the mark the process as dumpable with
libc::syscall(libc::SYS_prctl, PR_SET_DUMPABLE, 1, 0, 0, 0)otherwise most/all ptrace operations will fail. You might also run into problems using minidumper in the same process, it was never designed for that so it has no protections against suspending the thread that is currently executing, the man page doesn't say anything AFAICT about special behavior for attaching to the currently executing thread, so I'm assuming it will actually send SIGSTOP to the thread and dead lock your program, so you could try adding logic to ignore stopping the thread if it is the same thread id as the current thread.simon-fu commentedon Jul 8, 2022
libc::syscall(libc::SYS_prctl, PR_SET_DUMPABLE, 1, 0, 0, 0) did not work and still "No threads left to suspend out of 9"
I give up and plan to dump in another process
Thank you very much @Jake-Shadle