Skip to content
This repository was archived by the owner on Jun 27, 2018. It is now read-only.

Commit 001b0c3

Browse files
committed
re-add backtrace functionality
1 parent 7e6e0ab commit 001b0c3

File tree

4 files changed

+66
-1
lines changed

4 files changed

+66
-1
lines changed

src/bin/playbot.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ fn get_rust_versions(cache: &Cache) -> Vec<String> {
3333
let (status, output) = cache.exec(*channel,
3434
"rustc",
3535
vec![String::from("-V")],
36+
vec![],
3637
String::new()).unwrap();
3738
assert!(status.success(), "couldn't get version (this currently needs to run as root)");
3839
let version = str::from_utf8(&output).unwrap();
@@ -84,6 +85,7 @@ impl Playbot {
8485
let (_status, output) = try!(self.cache.exec(channel,
8586
"/usr/local/bin/evaluate.sh",
8687
Vec::new(),
88+
Vec::new(),
8789
String::from(full_code)));
8890

8991
let output_merged = output.splitn(2, |b| *b == b'\xff')

src/bin/playpen.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ struct EvaluateReq {
7878
optimize: Option<String>,
7979
separate_output: Option<bool>,
8080
code: String,
81+
backtrace: Option<String>,
8182
}
8283

8384
fn evaluate(req: &mut Request) -> IronResult<Response> {
@@ -90,6 +91,7 @@ fn evaluate(req: &mut Request) -> IronResult<Response> {
9091
let version = itry!(data.version.map(|v| v.parse()).unwrap_or(Ok(ReleaseChannel::Stable)));
9192
let opt = itry!(data.optimize.map(|opt| opt.parse()).unwrap_or(Ok(OptLevel::O2)));
9293
let separate_output = data.separate_output.unwrap_or(false);
94+
let backtrace = itry!(data.backtrace.map(|b| b.parse()).unwrap_or(Ok(Backtrace::Auto)));
9395

9496
let mut args = vec![String::from("-C"), format!("opt-level={}", opt.as_u8())];
9597
if opt == OptLevel::O0 {
@@ -102,10 +104,16 @@ fn evaluate(req: &mut Request) -> IronResult<Response> {
102104
args.push(String::from("--test"));
103105
}
104106

107+
let mut env = vec![];
108+
if backtrace.is_requested(opt == OptLevel::O0) {
109+
env.push(("RUST_BACKTRACE".into(), "1".into()));
110+
}
111+
105112
let cache = req.extensions.get::<AddCache>().unwrap();
106113
let (_status, output) = itry!(cache.exec(version,
107114
"/usr/local/bin/evaluate.sh",
108115
args,
116+
env,
109117
data.code));
110118

111119
let mut obj = json::Object::new();
@@ -141,6 +149,7 @@ struct CompileReq {
141149
optimize: Option<String>,
142150
emit: Option<String>,
143151
code: String,
152+
backtrace: Option<String>,
144153
}
145154

146155
fn compile(req: &mut Request) -> IronResult<Response> {
@@ -153,6 +162,7 @@ fn compile(req: &mut Request) -> IronResult<Response> {
153162
let version = itry!(data.version.map(|v| v.parse()).unwrap_or(Ok(ReleaseChannel::Stable)));
154163
let opt = itry!(data.optimize.map(|opt| opt.parse()).unwrap_or(Ok(OptLevel::O2)));
155164
let emit = itry!(data.emit.map(|emit| emit.parse()).unwrap_or(Ok(CompileOutput::Asm)));
165+
let backtrace = itry!(data.backtrace.map(|b| b.parse()).unwrap_or(Ok(Backtrace::Auto)));
156166

157167
let mut args = vec![
158168
String::from("-C"),
@@ -170,10 +180,16 @@ fn compile(req: &mut Request) -> IronResult<Response> {
170180
args.push(String::from("--color=always"));
171181
}
172182

183+
let mut env = vec![];
184+
if backtrace.is_requested(opt == OptLevel::O0) {
185+
env.push(("RUST_BACKTRACE".into(), "1".into()));
186+
}
187+
173188
let cache = req.extensions.get::<AddCache>().unwrap();
174189
let (_status, output) = itry!(cache.exec(version,
175190
"/usr/local/bin/compile.sh",
176191
args,
192+
env,
177193
data.code));
178194
let mut split = output.splitn(2, |b| *b == b'\xff');
179195
let rustc = String::from_utf8(split.next().unwrap().into()).unwrap();
@@ -198,6 +214,7 @@ fn compile(req: &mut Request) -> IronResult<Response> {
198214
struct FormatReq {
199215
version: Option<String>,
200216
code: String,
217+
backtrace: Option<String>,
201218
}
202219

203220
fn format(req: &mut Request) -> IronResult<Response> {
@@ -206,11 +223,18 @@ fn format(req: &mut Request) -> IronResult<Response> {
206223

207224
let data: FormatReq = itry!(json::decode(&body));
208225
let version = itry!(data.version.map(|v| v.parse()).unwrap_or(Ok(ReleaseChannel::Stable)));
226+
let backtrace = itry!(data.backtrace.map(|b| b.parse()).unwrap_or(Ok(Backtrace::Auto)));
227+
228+
let mut env = vec![];
229+
if backtrace == Backtrace::Always {
230+
env.push(("RUST_BACKTRACE".into(), "1".into()));
231+
}
209232

210233
let cache = req.extensions.get::<AddCache>().unwrap();
211234
let (status, output) = itry!(cache.exec(version,
212235
"rustfmt",
213236
Vec::new(),
237+
env,
214238
data.code));
215239
let output = String::from_utf8(output).unwrap();
216240
let mut response_obj = json::Object::new();

src/docker.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub struct Container {
1515
impl Container {
1616
pub fn new(cmd: &str,
1717
args: &[String],
18+
env: &[(String, String)],
1819
name: &str) -> io::Result<Container> {
1920
let out = try!(run(Command::new("docker")
2021
.arg("create")
@@ -24,6 +25,7 @@ impl Container {
2425
.arg("--pids-limit=20")
2526
.arg("--security-opt=no-new-privileges")
2627
.arg("--interactive")
28+
.args(&env.iter().map(|&(ref k, ref v)| format!("-e{}={}", k, v)).collect::<Vec<_>>())
2729
.arg(name)
2830
.arg(cmd)
2931
.stderr(Stdio::inherit())

src/lib.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ struct CacheKey {
6969
channel: ReleaseChannel,
7070
cmd: String,
7171
args: Vec<String>,
72+
env: Vec<(String, String)>,
7273
input: String,
7374
}
7475

@@ -84,13 +85,15 @@ impl Cache {
8485
channel: ReleaseChannel,
8586
cmd: &str,
8687
args: Vec<String>,
88+
env: Vec<(String, String)>,
8789
input: String)
8890
-> io::Result<(ExitStatus, Vec<u8>)> {
8991
// Build key to look up
9092
let key = CacheKey {
9193
channel: channel,
9294
cmd: cmd.to_string(),
9395
args: args,
96+
env: env,
9497
input: input,
9598
};
9699
let mut cache = self.cache.lock().unwrap();
@@ -106,7 +109,7 @@ impl Cache {
106109
};
107110
let container = format!("rust-playpen-{}", chan);
108111

109-
let container = try!(Container::new(cmd, &key.args, &container));
112+
let container = try!(Container::new(cmd, &key.args, &key.env, &container));
110113

111114
let tuple = try!(container.run(key.input.as_bytes(), Duration::new(5, 0)));
112115
let (status, mut output, timeout) = tuple;
@@ -145,6 +148,36 @@ impl FromStr for AsmFlavor {
145148
}
146149
}
147150

151+
#[derive(Debug, PartialEq, Eq)]
152+
pub enum Backtrace {
153+
Never,
154+
Always,
155+
Auto,
156+
}
157+
158+
impl Backtrace {
159+
pub fn is_requested(&self, debug: bool) -> bool {
160+
match *self {
161+
Backtrace::Never => false,
162+
Backtrace::Always => true,
163+
Backtrace::Auto => debug,
164+
}
165+
}
166+
}
167+
168+
impl FromStr for Backtrace {
169+
type Err = StringError;
170+
171+
fn from_str(s: &str) -> Result<Self, Self::Err> {
172+
match s {
173+
"0" => Ok(Backtrace::Never),
174+
"1" => Ok(Backtrace::Always),
175+
"2" => Ok(Backtrace::Auto),
176+
_ => Err(StringError(format!("unknown backtrace setting {}", s))),
177+
}
178+
}
179+
}
180+
148181
#[derive(Debug, PartialEq, Eq)]
149182
pub enum OptLevel {
150183
O0,
@@ -249,6 +282,7 @@ mod tests {
249282
let (status, out) = cache.exec(ReleaseChannel::Stable,
250283
"/usr/local/bin/evaluate.sh",
251284
Vec::new(),
285+
Vec::new(),
252286
input.to_string()).unwrap();
253287
assert!(status.success());
254288
assert_eq!(out, &[0xff, b'H', b'e', b'l', b'l', b'o', b'\n']);
@@ -267,6 +301,7 @@ mod tests {
267301
let (status, out) = cache.exec(ReleaseChannel::Stable,
268302
"/usr/local/bin/evaluate.sh",
269303
Vec::new(),
304+
Vec::new(),
270305
input.to_string()).unwrap();
271306
assert!(!status.success());
272307
assert!(String::from_utf8_lossy(&out).contains("timeout triggered"));
@@ -281,6 +316,7 @@ mod tests {
281316
let (status, out) = cache.exec(ReleaseChannel::Stable,
282317
"/usr/local/bin/compile.sh",
283318
vec![String::from("--emit=llvm-ir")],
319+
vec![],
284320
input.to_string()).unwrap();
285321

286322
assert!(status.success());
@@ -300,6 +336,7 @@ mod tests {
300336
let (status, out) = cache.exec(ReleaseChannel::Stable,
301337
"rustfmt",
302338
Vec::new(),
339+
Vec::new(),
303340
input.to_string()).unwrap();
304341
assert!(status.success());
305342
assert!(String::from_utf8(out).unwrap().contains(r#""Hello""#))

0 commit comments

Comments
 (0)