-
Notifications
You must be signed in to change notification settings - Fork 3.4k
[EH] Check if Exception.stack is writable #21050
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Apparently `WebAssembly.Exception.stack` has been `readonly` all along and I wasn't aware. But I wonder why this has to be `readonly`, and currently writing to this property works in Chrome and Node and fails in Firefox. I'll ask in the EH repo whether this should be `readonly`, but in the meantime, we check if this is writable before writing to it. Temporarily fixes emscripten-core#21044. Not sure how to test this... Do we run Firefox tests?
Yes, we run all browser tests in firefox by default, so just adding a test to |
src/library_exceptions.js
Outdated
// and it is implemented as writable in Chrome and Node. Will check the | ||
// 'writable' condition for now and later resolve this by either deleting | ||
// this altogether or removing this condition check. | ||
if (Object.getOwnPropertyDescriptor(e, 'stack').writable) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Combine this with the above into a single if
?
Did you verify that this is indeed readonly on FF for you locally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Combined within a single if
. No I haven't verified that locally because I don't have FF installed... I'll add a browser test so it will be confirmed by the CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend confirming the issue locally, just to be sure. Is there some reason you don't want to install FF?
Added a browser test. I don't check the text of stack traces there because we check (the simplified version of) it in |
test/test_browser.py
Outdated
''') | ||
self.emcc_args = ['-g', '-fwasm-exceptions'] | ||
self.set_setting('EXCEPTION_STACK_TRACES', 1) | ||
self.btest_exit('main.c') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a big deal but I wonder if this test could run the spidermonkey command line vm (and be part of test_core.py)?
Looking at our circleci config it looks like we already run test_demangle_stacks_symbol_map
under spidermonkey.
If you want to try doing this locally you can use jsvu
to install spidermonkey and do something like this your .emscripten
:
SPIDERMONKEY_ENGINE = [os.path.expanduser('~/.jsvu/bin/spidermonkey')]
JS_ENGINES = [SPIDERMONKEY_ENGINE]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK this gets tricky... Yeah I installed spidermonkey and moved the test to test_core.py
, with which I added a few functions and decorators for spidermonkey.
One funny thing is spidermonkey doesn't even seem to return anything with Object.getOwnPropertyDescriptor(e, 'stack');
, so it is not possible to check if writable
is set. So I had to split it again into two if
s:
if (e.stack) {
var pd = Object.getOwnPropertyDescriptor(e, 'stack');
if (pd && pd.writable) {
var arr = e.stack.split('\n');
arr.splice(1,1);
e.stack = arr.join('\n');
}
}
But the funny thing is, my spidermonkey doesn't seem to print
TypeError: setting getter-only property "stack"
as in #21044. It just ignores whatever I set it to, but doesn't error out:
js> var tag = new WebAssembly.Tag({parameters: ["i32"]});
js> var ex = new WebAssembly.Exception(tag, [42], {traceStack: true});
js> ex.stack
"@typein:2:10\n"
js> ex.stack = "abc";
"abc"
js> ex.stack
"@typein:2:10\n"
My spidermonkey version is
aheejin@aheejin:~/emscripten$ spidermonkey --version
JavaScript-C122.0
So, yeah, I updated the test but it is not really testing what I want to test, because the way I can think of to test this is to check if the error string contains setting getter-only property "stack"
(because, due to exception, the test fails anyway), and now my spidermonkey doesn't emit that string. Not sure if that's due to version differences, or due to the difference between the browser and the shell..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spidermonkey doesn't even seem to return anything with
Object.getOwnPropertyDescriptor(e, 'stack')
That's because, like all WebIDL attributes, it's a prototype-placed accessor, not an own property. WebIDL readonly
attributes are implemented as prototype-placed getters without corresponding setters. Chrome is in violation of the spec in using an own property instead.
As such the way to check is something like
function propertyWritable(obj, prop) {
let desc = Object.getOwnPropertyDescriptor(obj, prop);
if (!desc) {
let proto = Object.getPrototypeOf(obj);
return proto == null || propertyWritable(proto, prop);
}
return "writable" in desc
? desc.writable
: typeof desc.set === "function";
}
propertyWritable(new WebAssembly.Exception(new WebAssembly.Tag({parameters: ["i32"]}), [42], {traceStack: true}), 'stack'); // true in chrome, false in FF
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If setting .stack
is not spec compliant then we should probably just not do it... even though its currently possible on chrome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having stack
be writable isn't compliant, but if you do want to set the property, you could do Object.defineProperty(e, 'stack', { value: whatever, configurable: true, writable: true })
and that would work even in browsers where .stack
is non-writable. defineProperty
works even for readonly
properties.
(No comment on whether you should do this, just pointing out options.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the info! But yeah, after all, I think it'd be better not to do this given that this is not spec compliant. Will close this in favor of #21065.
Apparently
WebAssembly.Exception.stack
has beenreadonly
all along and I wasn't aware. But I wonder why this has to bereadonly
, and currently writing to this property works in Chrome and Node and fails in Firefox. I'll ask in the EH repo whether this should bereadonly
, but in the meantime, we check if this is writable before writing to it.Temporarily fixes #21044.
Not sure how to test this... Do we run Firefox tests?