@@ -81,6 +81,51 @@ unsafe fn emit_backtrace_by_frames(
8181    Ok ( ( ) ) 
8282} 
8383
84+ 
85+ // libunwind structures and functions 
86+ #[ repr( C ) ]  
87+ struct  UnwContext ( [ u8 ;  1024 ] ) ;  // Placeholder size for unw_context_t 
88+ 
89+ #[ repr( C ) ]  
90+ struct  UnwCursor ( [ u8 ;  1024 ] ) ;  // Placeholder size for unw_cursor_t 
91+ 
92+ extern  "C"  { 
93+     fn  _ULx86_64_init_local ( cursor :  * mut  UnwCursor ,  context :  * mut  UnwContext )  -> i32 ; 
94+     fn  _ULx86_64_step ( cursor :  * mut  UnwCursor )  -> i32 ; 
95+     fn  _ULx86_64_get_reg ( cursor :  * mut  UnwCursor ,  reg :  i32 ,  valp :  * mut  u64 )  -> i32 ; 
96+ } 
97+ 
98+ const  UNW_REG_IP :  i32  = 16 ;  // Register number for Instruction Pointer 
99+ const  UNW_REG_SP :  i32  = 17 ;  // Register number for Stack Pointer 
100+ 
101+ fn  emit_backtrace_libuwnind ( w :  & mut  impl  Write ,  ucontext :  * const  ucontext_t )  -> anyhow:: Result < ( ) >  { 
102+     unsafe  { 
103+         let  mut  context = UnwContext ( [ 0 ;  1024 ] ) ; 
104+         let  mut  cursor = UnwCursor ( [ 0 ;  1024 ] ) ; 
105+ 
106+         if  _ULx86_64_init_local ( & mut  cursor,  & mut  context)  != 0  { 
107+             writeln ! ( w,  "Failed to initialize libunwind cursor" ) ?; 
108+             return  Ok ( ( ) ) ; 
109+         } 
110+ 
111+         writeln ! ( w,  "{DD_CRASHTRACK_BEGIN_STACKTRACE}" ) ?; 
112+         while  _ULx86_64_step ( & mut  cursor)  > 0  { 
113+             let  mut  ip:  u64  = 0 ; 
114+             let  mut  sp:  u64  = 0 ; 
115+             if  _ULx86_64_get_reg ( & mut  cursor,  UNW_REG_IP ,  & mut  ip)  == 0  &&
116+                _ULx86_64_get_reg ( & mut  cursor,  UNW_REG_SP ,  & mut  sp)  == 0  { 
117+                 writeln ! ( w,  "{{ \" ip\" : \" {:x}\" , \" sp\" : \" {:x}\"  }}" ,  ip,  sp) ?; 
118+             }  else  { 
119+                 writeln ! ( w,  "Failed to get registers" ) ?; 
120+                 break ; 
121+             } 
122+         } 
123+         writeln ! ( w,  "{DD_CRASHTRACK_END_STACKTRACE}" ) ?; 
124+     } 
125+     Ok ( ( ) ) 
126+ } 
127+ 
128+ 
84129pub ( crate )  fn  emit_crashreport ( 
85130    pipe :  & mut  impl  Write , 
86131    config :  & CrashtrackerConfiguration , 
@@ -109,7 +154,9 @@ pub(crate) fn emit_crashreport(
109154    // https://doc.rust-lang.org/src/std/backtrace.rs.html#332 
110155    // Do this last, so even if it crashes, we still get the other info. 
111156    if  config. resolve_frames  != StacktraceCollection :: Disabled  { 
112-         unsafe  {  emit_backtrace_by_frames ( pipe,  config. resolve_frames ) ? } ; 
157+         // todo: add a switch between musl / glibc 
158+         // unsafe { emit_backtrace_by_frames(pipe, config.resolve_frames)? }; 
159+         emit_backtrace_libuwnind ( pipe,  ucontext) ?; 
113160    } 
114161    writeln ! ( pipe,  "{DD_CRASHTRACK_DONE}" ) ?; 
115162    pipe. flush ( ) ?; 
0 commit comments