Skip to content

Commit f034141

Browse files
committedAug 18, 2018
Auto merge of #53436 - cuviper:trace_fn-stop, r=alexcrichton
std: stop backtracing when the frames are full This is a defensive measure to mitigate the infinite unwind loop seen in #53372. That case will still repeatedly unwind `__rust_try`, but now it will at least stop when `cx.frames` is full. r? @alexcrichton
2 parents a3ad012 + f4e8d57 commit f034141

File tree

3 files changed

+30
-24
lines changed

3 files changed

+30
-24
lines changed
 

‎src/libstd/sys/cloudabi/backtrace.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ extern "C" fn trace_fn(
6464
arg: *mut libc::c_void,
6565
) -> uw::_Unwind_Reason_Code {
6666
let cx = unsafe { &mut *(arg as *mut Context) };
67+
if cx.idx >= cx.frames.len() {
68+
return uw::_URC_NORMAL_STOP;
69+
}
70+
6771
let mut ip_before_insn = 0;
6872
let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void };
6973
if !ip.is_null() && ip_before_insn == 0 {
@@ -73,14 +77,12 @@ extern "C" fn trace_fn(
7377
}
7478

7579
let symaddr = unsafe { uw::_Unwind_FindEnclosingFunction(ip) };
76-
if cx.idx < cx.frames.len() {
77-
cx.frames[cx.idx] = Frame {
78-
symbol_addr: symaddr as *mut u8,
79-
exact_position: ip as *mut u8,
80-
inline_context: 0,
81-
};
82-
cx.idx += 1;
83-
}
80+
cx.frames[cx.idx] = Frame {
81+
symbol_addr: symaddr as *mut u8,
82+
exact_position: ip as *mut u8,
83+
inline_context: 0,
84+
};
85+
cx.idx += 1;
8486

8587
uw::_URC_NO_REASON
8688
}

‎src/libstd/sys/redox/backtrace/tracing.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ pub fn unwind_backtrace(frames: &mut [Frame])
6868
extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
6969
arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
7070
let cx = unsafe { &mut *(arg as *mut Context) };
71+
if cx.idx >= cx.frames.len() {
72+
return uw::_URC_NORMAL_STOP;
73+
}
74+
7175
let mut ip_before_insn = 0;
7276
let mut ip = unsafe {
7377
uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
@@ -94,14 +98,12 @@ extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
9498
unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
9599
};
96100

97-
if cx.idx < cx.frames.len() {
98-
cx.frames[cx.idx] = Frame {
99-
symbol_addr: symaddr as *mut u8,
100-
exact_position: ip as *mut u8,
101-
inline_context: 0,
102-
};
103-
cx.idx += 1;
104-
}
101+
cx.frames[cx.idx] = Frame {
102+
symbol_addr: symaddr as *mut u8,
103+
exact_position: ip as *mut u8,
104+
inline_context: 0,
105+
};
106+
cx.idx += 1;
105107

106108
uw::_URC_NO_REASON
107109
}

‎src/libstd/sys/unix/backtrace/tracing/gcc_s.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ pub fn unwind_backtrace(frames: &mut [Frame])
6868
extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
6969
arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
7070
let cx = unsafe { &mut *(arg as *mut Context) };
71+
if cx.idx >= cx.frames.len() {
72+
return uw::_URC_NORMAL_STOP;
73+
}
74+
7175
let mut ip_before_insn = 0;
7276
let mut ip = unsafe {
7377
uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
@@ -94,14 +98,12 @@ extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
9498
unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
9599
};
96100

97-
if cx.idx < cx.frames.len() {
98-
cx.frames[cx.idx] = Frame {
99-
symbol_addr: symaddr as *mut u8,
100-
exact_position: ip as *mut u8,
101-
inline_context: 0,
102-
};
103-
cx.idx += 1;
104-
}
101+
cx.frames[cx.idx] = Frame {
102+
symbol_addr: symaddr as *mut u8,
103+
exact_position: ip as *mut u8,
104+
inline_context: 0,
105+
};
106+
cx.idx += 1;
105107

106108
uw::_URC_NO_REASON
107109
}

0 commit comments

Comments
 (0)
Please sign in to comment.