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

Commit

Permalink
Merge pull request #191 from respeccing/turn_on_backtrace_when_Debug
Browse files Browse the repository at this point in the history
UI option to turn on backtrace (RUST_BACKTRACE=1) --- off by default; (and also embed it in shared urls)
  • Loading branch information
alexcrichton committed Apr 1, 2016
2 parents 9a7e75c + 20ca18c commit e8a768b
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 31 deletions.
6 changes: 6 additions & 0 deletions static/web.html
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@
<option>att</option>
<option>intel</option>
</select>
<p><label for=backtrace title="Whether to set the shell environment var RUST_BACKTRACE and thus show the backtrace in the output! eg. to quickly test this run: fn main() { panic!() }">Backtrace:</label>
<select name=backtrace id=backtrace>
<option title="RUST_BACKTRACE is not set" value="0">off</option>
<option title="export RUST_BACKTRACE=1" value="1">on</option>
<option title="'auto' means turn this on only when Mode: Debug but not when Mode: Release" value="2">auto</option>
</select>
</div
></div>
</form>
Expand Down
50 changes: 36 additions & 14 deletions static/web.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@
result.parentNode.style.visibility = "";
}

function evaluate(result, code, version, optimize, button, test) {
send("evaluate.json", {code: code, version: version, optimize: optimize, test: !!test, separate_output: true, color: true},
function evaluate(result, code, version, optimize, button, test, backtrace) {
send("evaluate.json", {code: code, version: version, optimize: optimize, test: !!test, separate_output: true, color: true, backtrace: backtrace },
function(object) {
var samp, pre;
set_result(result);
Expand Down Expand Up @@ -174,10 +174,10 @@
}, button, test ? "Running tests…" : "Running…", result);
}

function compile(emit, result, code, version, optimize, button) {
function compile(emit, result, code, version, optimize, button, backtrace) {
var syntax = document.getElementById('asm-flavor').value;
send("compile.json", {emit: emit, code: code, version: version, optimize: optimize,
color: true, highlight: true, syntax: syntax}, function(object) {
color: true, highlight: true, syntax: syntax, backtrace: backtrace}, function(object) {
if ("error" in object) {
set_result(result, "<pre class=\"rustc-output rustc-errors\"><samp></samp></pre>");
result.firstChild.firstChild.innerHTML = formatCompilerOutput(object.error);
Expand Down Expand Up @@ -233,10 +233,11 @@
result.parentNode.style.visibility = "";
}

function shareGist(result, version, code, button) {
function shareGist(result, version, code, button, backtraceval) {
// only needed for the "shrinking" animation
var full_url = "https://play.rust-lang.org/?code=" + encodeURIComponent(code) +
"&version=" + encodeURIComponent(version);
"&version=" + encodeURIComponent(version) +
"&backtrace=" + encodeURIComponent(backtraceval);
var url = "https://api.github.com/gists";
button.disabled = true;

Expand Down Expand Up @@ -275,7 +276,8 @@

var play_url = "https://play.rust-lang.org/?gist=" +
encodeURIComponent(gist_id) + "&version=" +
encodeURIComponent(version);
encodeURIComponent(version) +
"&backtrace=" + encodeURIComponent(backtraceval);


var link = result.firstChild.firstElementChild;
Expand All @@ -301,9 +303,10 @@
);
}

function share(result, version, code, button) {
function share(result, version, code, button, backtraceval) {
var playurl = "https://play.rust-lang.org/?code=" + encodeURIComponent(code);
playurl += "&version=" + encodeURIComponent(version);
playurl += "&backtrace=" + encodeURIComponent(backtraceval);
if (playurl.length > 5000) {
set_result(result, "<p class=error>Sorry, your code is too long to share this way." +
"<p class=error-explanation>At present, sharing produces a link containing the" +
Expand Down Expand Up @@ -482,6 +485,7 @@
var mode;
var query;
var asm_flavor;
var backtrace;

function updateEvaluateAction(code) {
// A very simple pair of heuristics; there’s no point in doing more, IMO.
Expand All @@ -503,7 +507,8 @@
}
evaluate(result, session.getValue(), getRadioValue("version"),
getRadioValue("optimize"), evaluateButton,
evaluateAction === "test");
evaluateAction === "test",
backtrace.value);
}

var COLOR_CODES = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
Expand Down Expand Up @@ -552,6 +557,7 @@
clearResultButton = document.getElementById("clear-result");
keyboard = document.getElementById("keyboard");
asm_flavor = document.getElementById("asm-flavor");
backtrace = document.getElementById("backtrace");
themes = document.getElementById("themes");
editor = ace.edit("editor");
set_result.editor = editor;
Expand Down Expand Up @@ -589,6 +595,11 @@
asm_flavor.value = flavor;
}

var vbacktrace = optionalLocalStorageGetItem("backtrace");
if (vbacktrace !== null) {
backtrace.value = vbacktrace;
}

query = getQueryParameters();
if ("code" in query) {
session.setValue(query.code);
Expand All @@ -610,6 +621,12 @@
}
}

if ("backtrace" in query) {
if (backtrace !== null) {
backtrace.value = query.backtrace;
}
}

if (query.run === "1") {
doEvaluate();
} else {
Expand Down Expand Up @@ -637,6 +654,11 @@
optionalLocalStorageSetItem("asm_flavor", flavor);
};

backtrace.onkeyup = backtrace.onchange = function() {
var vbacktrace = backtrace.options[backtrace.selectedIndex].value;
optionalLocalStorageSetItem("backtrace", vbacktrace);
};

evaluateButton.onclick = function() {
doEvaluate(true);
};
Expand All @@ -656,30 +678,30 @@

asmButton.onclick = function() {
compile("asm", result, session.getValue(), getRadioValue("version"),
getRadioValue("optimize"), asmButton);
getRadioValue("optimize"), asmButton, backtrace.value);
};

irButton.onclick = function() {
compile("llvm-ir", result, session.getValue(), getRadioValue("version"),
getRadioValue("optimize"), irButton);
getRadioValue("optimize"), irButton, backtrace.value);
};

mirButton.onclick = function() {
document.getElementById("version-nightly").checked = true;
compile("mir", result, session.getValue(), getRadioValue("version"),
getRadioValue("optimize"), mirButton);
getRadioValue("optimize"), mirButton, backtrace.value);
};

formatButton.onclick = function() {
format(result, session, getRadioValue("version"), formatButton);
};

shareButton.onclick = function() {
share(result, getRadioValue("version"), session.getValue(), shareButton);
share(result, getRadioValue("version"), session.getValue(), shareButton, backtrace.value);
};

gistButton.onclick = function() {
shareGist(result, getRadioValue("version"), session.getValue(), gistButton);
shareGist(result, getRadioValue("version"), session.getValue(), gistButton, backtrace.value);
};

configureEditorButton.onclick = function() {
Expand Down
50 changes: 33 additions & 17 deletions web.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import functools
import os
import sys
import shlex #for shlex.quote() needed only when backtrace is on, to escape args

from bottle import get, request, response, route, run, static_file
from pygments import highlight
Expand Down Expand Up @@ -32,7 +33,13 @@ def serve_static(path):
return static_file(path, root="static")

@functools.lru_cache(maxsize=256)
def execute(version, command, arguments, code):
def execute(version, command, arguments, code, show_backtrace):
if show_backtrace:
escapedargs=""
for arg in arguments:
escapedargs += " " + shlex.quote(arg)
arguments = ("-c", "export RUST_BACKTRACE=1; " + command + escapedargs)
command = "/usr/bin/dash"
print("running:", version, command, arguments, file=sys.stderr, flush=True)
return playpen.execute(version, command, arguments, code)

Expand All @@ -57,22 +64,31 @@ def wrapper(*args, **kwargs):
return wrapper
return decorator

def init_args_get_bt(optimize, color, backtrace_str):
args = ["-C", "opt-level=" + optimize]
if "1" == backtrace_str or ( "2" == backtrace_str and "0" == optimize ):
show_backtrace = True
else:
show_backtrace = False
if "0" == optimize:
args.append("-g")
if color:
args.append("--color=always")
return (args, show_backtrace)

@route("/evaluate.json", method=["POST", "OPTIONS"])
@enable_post_cors
@extractor("backtrace", "0", ("0", "1", "2"))
@extractor("color", False, (True, False))
@extractor("test", False, (True, False))
@extractor("version", "stable", ("stable", "beta", "nightly"))
@extractor("optimize", "2", ("0", "1", "2", "3"))
def evaluate(optimize, version, test, color):
args = ["-C", "opt-level=" + optimize]
if optimize == "0":
args.append("-g")
if color:
args.append("--color=always")
def evaluate(optimize, version, test, color, backtrace_str):
args, show_backtrace = init_args_get_bt(optimize, color, backtrace_str)
if test:
args.append("--test")

out, _ = execute(version, "/usr/local/bin/evaluate.sh", tuple(args), request.json["code"])
out, _ = execute(version, "/usr/local/bin/evaluate.sh", tuple(args), request.json["code"], show_backtrace)

if request.json.get("separate_output") is True:
split = out.split(b"\xff", 1)
Expand All @@ -87,27 +103,27 @@ def evaluate(optimize, version, test, color):

@route("/format.json", method=["POST", "OPTIONS"])
@enable_post_cors
@extractor("optimize", "2", ("0", "1", "2", "3"))
@extractor("backtrace", "0", ("0", "1", "2"))
@extractor("version", "stable", ("stable", "beta", "nightly"))
def format(version):
out, rc = execute(version, "/usr/bin/rustfmt", (), request.json["code"])
def format(version, backtrace_str, optimize):
_, show_backtrace = init_args_get_bt(optimize, None, backtrace_str)
out, rc = execute(version, "/usr/bin/rustfmt", (), request.json["code"], show_backtrace)
if rc:
return {"error": out.decode()}
else:
return {"result": out.decode()}

@route("/compile.json", method=["POST", "OPTIONS"])
@enable_post_cors
@extractor("backtrace", "0", ("0", "1", "2"))
@extractor("syntax", "att", ("att", "intel"))
@extractor("color", False, (True, False))
@extractor("version", "stable", ("stable", "beta", "nightly"))
@extractor("optimize", "2", ("0", "1", "2", "3"))
@extractor("emit", "asm", ("asm", "llvm-ir", "mir"))
def compile(emit, optimize, version, color, syntax):
args = ["-C", "opt-level=" + optimize]
if optimize == "0":
args.append("-g")
if color:
args.append("--color=always")
def compile(emit, optimize, version, color, syntax, backtrace_str):
args, show_backtrace = init_args_get_bt(optimize, color, backtrace_str)
if syntax:
args.append("-C")
args.append("llvm-args=-x86-asm-syntax=%s" % syntax)
Expand All @@ -116,7 +132,7 @@ def compile(emit, optimize, version, color, syntax):
args.append("--unpretty=mir")
else:
args.append("--emit=" + emit)
out, _ = execute(version, "/usr/local/bin/compile.sh", tuple(args), request.json["code"])
out, _ = execute(version, "/usr/local/bin/compile.sh", tuple(args), request.json["code"], show_backtrace)
split = out.split(b"\xff", 1)
if len(split) == 2:
rustc_output = split[0].decode()
Expand Down

0 comments on commit e8a768b

Please sign in to comment.