-
Notifications
You must be signed in to change notification settings - Fork 129
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
feat: improve error report #844
base: master
Are you sure you want to change the base?
Conversation
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 don't think JS_SetPropertyInternal2 is the right place for this because then we're adding a property as a side effect of adding another property.
A better place is when constructing the backtrace, maybe? (But we're already calling get_func_name there so why isn't that working?)
- Going through JS_ToCString and JS_FreeCString is kind of inefficient. It's better to split up get_func_name into two parts, one that looks up the JSValue, and one that turns it into a C string.
const char* name = get_func_name(ctx, val); | ||
if (strcmp(name, "") == 0) { |
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.
Minor style issues: alignment + star leans right; applies to the closing brace too
Correct me if I'm wrong but you want to set the name if it's not empty, right? Also, get_func_name can return NULL
const char* name = get_func_name(ctx, val); | |
if (strcmp(name, "") == 0) { | |
const char *name = get_func_name(ctx, val); | |
if (name && *name) { |
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 don't think JS_SetPropertyInternal2 is the right place for this because then we're adding a property as a side effect of adding another property.
It's anonymous function by definition function() {throw new Error('woof woof');};
It use the object property name as a fallback for easy debugging.
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.
Correct me if I'm wrong but you want to set the name if it's not empty, right?
Yeap. quickjs now already works when dog.bark
value is named function
var dog = {};
dog.bark = function c2() {
throw new Error('woof woof');
};
function makeStack() {
try {
dog.bark();
} catch (error) {
print(error.stack)
}
}
makeStack();
You can see it here http://k2.gengjiawen.com:8001/
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.
Yes, I understand that. I think in general it should be possible to recover that information from the JSStackFrame when the backtrace is built.
(I worked on something similar recently for constructors, although I haven't finished that yet.)
The problem I see with the approach in this PR is that it produces the wrong result in this example, right?
var a = {foo: function() { throw Error("fail") }}
var b = {bar: a.foo}
b.bar() // "foo" in stack trace
edit: cross-posted
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.
Yes, I understand that. I think in general it should be possible to recover that information from the JSStackFrame when the backtrace is built.
Yeap. Is there enough context when construct backtrace since this request the property info ? From what I see looks like quickjs not saving enough context for now.
The problem I see with the approach in this PR is that it produces the wrong result in this example, right?
Personally I think it's acceptable. the function is foo when defined.
v8 for reference
/tmp/6bfa5ab:1: Error: fail
var a = {foo: function() { throw Error("fail") }}
^
Error: fail
at Object.foo [as bar] (/tmp/6bfa5ab:1:34)
at /tmp/6bfa5ab:3:3
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.
Also, get_func_name can return NULL
Is this why the segment fault in ASAN ?
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.
Is there enough context when construct backtrace
The answer is a qualified "yes". I had it sort of working for constructors but in general no. I'll grant that making JS_CallInternal record that information is probably a lot more involved than your current approach.
That said, I still don't think JS_SetPropertyInternal2 is the proper place for that because that makes the .name property magically appear as an observable side effect of another operation.
After thinking about it some more, I think the right place is in the parser. We already parse something like this correctly:
var f = function() {} // f.name === "f"
And also:
var o = {f: function() {}} // o.f.name === "f"
But not:
var o = {}
o.f = function() {} // o.f.name === ""
fix: bellard/quickjs#93
currently for input
Engine behaviour
this PR: