Skip to content

Commit 519addf

Browse files
committed
Print stack overflow messages for Windows, Linux and OS X
1 parent 2eb4f43 commit 519addf

File tree

11 files changed

+746
-7
lines changed

11 files changed

+746
-7
lines changed

src/libgreen/simple.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl Runtime for SimpleTask {
8181
}
8282
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>> { None }
8383
fn stack_bounds(&self) -> (uint, uint) { fail!() }
84+
fn stack_guard(&self) -> Option<uint> { fail!() }
8485
fn can_block(&self) -> bool { true }
8586
fn wrap(self: Box<SimpleTask>) -> Box<Any+'static> { fail!() }
8687
}

src/libgreen/stack.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ impl Stack {
8282
}
8383
}
8484

85+
/// Point to the last writable byte of the stack
86+
pub fn guard(&self) -> *const uint {
87+
(self.start() as uint + page_size()) as *const uint
88+
}
89+
8590
/// Point to the low end of the allocated stack
8691
pub fn start(&self) -> *const uint {
8792
self.buf.as_ref().map(|m| m.data() as *const uint)

src/libgreen/task.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,13 @@ impl Runtime for GreenTask {
486486
c.current_stack_segment.end() as uint)
487487
}
488488

489+
fn stack_guard(&self) -> Option<uint> {
490+
let c = self.coroutine.as_ref()
491+
.expect("GreenTask.stack_guard called without a coroutine");
492+
493+
Some(c.current_stack_segment.guard() as uint)
494+
}
495+
489496
fn can_block(&self) -> bool { false }
490497

491498
fn wrap(self: Box<GreenTask>) -> Box<Any+'static> {

src/libnative/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
133133
rt::init(argc, argv);
134134
let mut exit_code = None;
135135
let mut main = Some(main);
136-
let mut task = task::new((my_stack_bottom, my_stack_top));
136+
let mut task = task::new((my_stack_bottom, my_stack_top),
137+
rt::thread::main_guard_page());
137138
task.name = Some(str::Slice("<main>"));
138139
drop(task.run(|| {
139140
unsafe {

src/libnative/task.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ use task;
3030
use std::task::{TaskBuilder, Spawner};
3131

3232
/// Creates a new Task which is ready to execute as a 1:1 task.
33-
pub fn new(stack_bounds: (uint, uint)) -> Box<Task> {
33+
pub fn new(stack_bounds: (uint, uint), stack_guard: uint) -> Box<Task> {
3434
let mut task = box Task::new();
3535
let mut ops = ops();
3636
ops.stack_bounds = stack_bounds;
37+
ops.stack_guard = stack_guard;
3738
task.put_runtime(ops);
3839
return task;
3940
}
@@ -45,6 +46,7 @@ fn ops() -> Box<Ops> {
4546
io: io::IoFactory::new(),
4647
// these *should* get overwritten
4748
stack_bounds: (0, 0),
49+
stack_guard: 0
4850
}
4951
}
5052

@@ -87,6 +89,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc():Send) {
8789
stack::record_os_managed_stack_bounds(my_stack - stack + 1024, my_stack);
8890
}
8991
let mut ops = ops;
92+
ops.stack_guard = rt::thread::current_guard_page();
9093
ops.stack_bounds = (my_stack - stack + 1024, my_stack);
9194

9295
let mut f = Some(f);
@@ -128,6 +131,8 @@ struct Ops {
128131
// native tasks necessarily know their precise bounds, hence this is
129132
// optional.
130133
stack_bounds: (uint, uint),
134+
135+
stack_guard: uint
131136
}
132137

133138
impl rt::Runtime for Ops {
@@ -151,6 +156,14 @@ impl rt::Runtime for Ops {
151156

152157
fn stack_bounds(&self) -> (uint, uint) { self.stack_bounds }
153158

159+
fn stack_guard(&self) -> Option<uint> {
160+
if self.stack_guard != 0 {
161+
Some(self.stack_guard)
162+
} else {
163+
None
164+
}
165+
}
166+
154167
fn can_block(&self) -> bool { true }
155168

156169
// This function gets a little interesting. There are a few safety and

src/librustrt/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ mod local_ptr;
5151
mod thread_local_storage;
5252
mod util;
5353
mod libunwind;
54+
mod stack_overflow;
5455

5556
pub mod args;
5657
pub mod bookkeeping;
@@ -92,6 +93,8 @@ pub trait Runtime {
9293
fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
9394
/// The (low, high) edges of the current stack.
9495
fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
96+
/// The last writable byte of the stack next to the guard page
97+
fn stack_guard(&self) -> Option<uint>;
9598
fn can_block(&self) -> bool;
9699

97100
// FIXME: This is a serious code smell and this should not exist at all.
@@ -113,6 +116,7 @@ pub fn init(argc: int, argv: *const *const u8) {
113116
args::init(argc, argv);
114117
local_ptr::init();
115118
at_exit_imp::init();
119+
thread::init();
116120
}
117121

118122
// FIXME(#14344) this shouldn't be necessary

0 commit comments

Comments
 (0)