@@ -14,14 +14,21 @@ thread_local! {
1414 static REPRS : RefCell <HashMap <u64 , Arc <str >>> = RefCell :: new( HashMap :: default ( ) ) ;
1515}
1616static mut START : Option < ( & ' static str , u32 ) > = None ;
17+ static mut START_ALT : Option < ( & ' static str , u32 ) > = None ;
1718
18- #[ track_caller]
1919pub fn set_backtrace_start ( file : & ' static str , line : u32 ) {
2020 unsafe {
2121 START = Some ( ( file, line) ) ;
2222 }
2323}
2424
25+ #[ doc( hidden) ]
26+ pub fn set_backtrace_start_alt ( file : & ' static str , line : u32 ) {
27+ unsafe {
28+ START_ALT = Some ( ( file, line) ) ;
29+ }
30+ }
31+
2532#[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
2633pub enum ErrorType {
2734 Client ,
@@ -83,7 +90,7 @@ pub trait ErrorDiagnostic: error::Error + 'static {
8390 }
8491}
8592
86- #[ derive( Debug , Clone ) ]
93+ #[ derive( Clone ) ]
8794pub struct Error < E > {
8895 inner : Box < ErrorInner < E > > ,
8996}
@@ -358,7 +365,8 @@ where
358365pub struct Backtrace ( Arc < str > ) ;
359366
360367impl Backtrace {
361- fn new ( loc : & Location < ' _ > ) -> Self {
368+ /// Create new backtrace
369+ pub fn new ( loc : & Location < ' _ > ) -> Self {
362370 let repr = FRAMES . with ( |c| {
363371 let mut cache = c. borrow_mut ( ) ;
364372 let mut idx = 0 ;
@@ -396,8 +404,13 @@ impl Backtrace {
396404 find_loc ( loc, & mut frames) ;
397405
398406 #[ allow( static_mut_refs) ]
399- if let Some ( start) = unsafe { START } {
400- find_loc_start ( start, & mut frames) ;
407+ {
408+ if let Some ( start) = unsafe { START } {
409+ find_loc_start ( start, & mut frames) ;
410+ }
411+ if let Some ( start) = unsafe { START_ALT } {
412+ find_loc_start ( start, & mut frames) ;
413+ }
401414 }
402415
403416 let bt = Bt ( & frames[ ..] ) ;
@@ -441,26 +454,27 @@ fn find_loc(loc: &Location<'_>, frames: &mut [Option<&BacktraceFrame>]) {
441454}
442455
443456fn find_loc_start ( loc : ( & str , u32 ) , frames : & mut [ Option < & BacktraceFrame > ] ) {
444- let mut idx = frames. len ( ) ;
445- while idx > 0 {
446- idx -= 1 ;
457+ let mut idx = 0 ;
458+ while idx < frames. len ( ) {
447459 if let Some ( frm) = & frames[ idx] {
448460 for sym in frm. symbols ( ) {
449461 if let Some ( fname) = sym. filename ( )
450462 && let Some ( lineno) = sym. lineno ( )
451463 && fname. ends_with ( loc. 0 )
452- && lineno == loc. 1
464+ && ( loc . 1 == 0 || lineno == loc. 1 )
453465 {
454- for f in frames. iter_mut ( ) . skip ( idx + 1 ) {
466+ for f in frames. iter_mut ( ) . skip ( idx) {
455467 if f. is_some ( ) {
456468 * f = None ;
457469 } else {
458470 return ;
459471 }
460472 }
473+ break ;
461474 }
462475 }
463476 }
477+ idx += 1 ;
464478 }
465479}
466480
@@ -502,6 +516,19 @@ impl fmt::Display for Backtrace {
502516 }
503517}
504518
519+ impl < E > fmt:: Debug for Error < E >
520+ where
521+ E : ErrorDiagnostic ,
522+ {
523+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
524+ f. debug_struct ( "Error" )
525+ . field ( "error" , & self . inner . error )
526+ . field ( "service" , & self . inner . service )
527+ . field ( "backtrace" , & self . inner . backtrace )
528+ . finish ( )
529+ }
530+ }
531+
505532impl < E > fmt:: Display for Error < E >
506533where
507534 E : ErrorDiagnostic ,
0 commit comments