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

UI option to turn on backtrace (RUST_BACKTRACE=1) --- off by default; (and also embed it in shared urls) #191

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
eaebca2
set RUST_BACKTRACE=1 when Debug build
respeccing Mar 28, 2016
19c9861
typo in comment
respeccing Mar 28, 2016
a147805
--backtrace does not need to be first arg anymore
respeccing Mar 29, 2016
a74eee4
fix wrong place for 'set'
respeccing Mar 29, 2016
31f7f81
forgot to also move the comment
respeccing Mar 29, 2016
533ed15
add option to toggle backtrace,under "Asm Flavor:"
respeccing Mar 29, 2016
7f96136
pass backtrace as arg to evaluate
respeccing Mar 29, 2016
a6cb525
make whitespace consistent
respeccing Mar 29, 2016
9539680
embed the backtrace setting in shared urls
respeccing Mar 29, 2016
2b489ec
simplify dash syntax as requested
respeccing Mar 29, 2016
86f915d
actually, let's use prepend here - it's safer
respeccing Mar 29, 2016
c88aca3
add backtrace logic to compile.sh too
respeccing Mar 29, 2016
a50b313
ensure web passes --backtrace to compile.sh
respeccing Mar 29, 2016
d50dcb0
update tooltip
respeccing Mar 29, 2016
709644f
remove confusing punctuation
respeccing Mar 29, 2016
6082cca
replace internal representations for backtrace
respeccing Mar 29, 2016
714236d
nitpicking
respeccing Mar 29, 2016
e25f1b0
typo
respeccing Mar 29, 2016
ebe8103
fix whitespace
respeccing Mar 29, 2016
b8f2d9e
moved common block into a function
respeccing Mar 30, 2016
662fab0
playpen.py: addin ability to pass env.vars
respeccing Mar 31, 2016
f65f1fd
comment too long
respeccing Mar 31, 2016
bf340cc
replace --backtrace with passing env.var directly
respeccing Mar 31, 2016
ad6a136
rustfmt of Format button is now backtrace affected
respeccing Mar 31, 2016
4fdf3b2
playpen.py: fix exporting valueless env.vars
respeccing Mar 31, 2016
14f2873
playpen.py: undo all previous modifications
respeccing Mar 31, 2016
20ca18c
simplified as requested
respeccing Mar 31, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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