-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
core: implement runtime flag to print warn on sync #1707
Conversation
@@ -335,6 +335,9 @@ NODE_DEPRECATED("Use DecodeWrite(isolate, ...)", | |||
return DecodeWrite(v8::Isolate::GetCurrent(), buf, buflen, val, encoding); | |||
}) | |||
|
|||
|
|||
void PrintSyncWarning(Environment* env); |
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.
@bnoordhuis I'm pretty sure node.h
isn't the correct place for this, but wasn't sure where else to place it.
8743a9f
to
19e77d3
Compare
Does this handle |
@ChALkeR Thanks. Figured I'd missed some. I'll add that. |
80926f2
to
066f492
Compare
@ChALkeR Added. @iojs/tc I've updated the implementation to store the needed value on |
066f492
to
d1e1744
Compare
I think this could be useful. 👍 |
isolate_, 10, v8::StackTrace::kDetailed); | ||
|
||
fprintf(stderr, "WARNING: Detected use of sync API\n"); | ||
for (int i = 0; i < stack->GetFrameCount() - 1; i++) { |
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.
Could we use Message::PrintCurrentStackTrace(isolate_, stderr)
so that v8 does the formatting? Since it's pretty complicated when you start to handle evals, constructors etc.
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.
That would make things much easier. Though there's a slight style issue that doesn't sit well with me. Here's an example output:
WARNING: Detected use of sync API
pbkdf2 (crypto.js:592:20)
Object.exports.pbkdf2Sync (crypto.js:583:10)
null._onTimeout (/tmp/x.js:8:10)
Timer.listOnTimeout (timers.js:89:15)
I would prefer the stack trace to look more like an error's stack trace with at
at the beginning of each line. But reimplementing the entire formatting would be a pain. I have the change ready and waiting but would like your thoughts on this before I push it up.
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.
oh I expected it to be in same format as you would get when doing new Error().stack
or Error.captureStackTrace
in javascript. Another option would be to call into javascript to get a formatted stack trace.
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.
Yeah. I see how complex the formatting is for the stack trace in CallSiteToString()
in deps/v8/src/message.js
.
@bnoordhuis If we were to call to JS, what would be the best way to do that from an env function?
The synchronous code has been run after diff --git a/src/node.cc b/src/node.cc
index 4cafe96..8dec8da 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -3887,6 +3887,9 @@ static void StartNodeInstance(void* arg) {
LoadEnvironment(env);
+ if (warn_on_sync)
+ env->set_warn_on_sync(true);
+
// Enable debugger
if (instance_data->use_debug_agent())
EnableDebug(env); |
d1e1744
to
343fc0e
Compare
Great idea. Implemented that change. |
8205884
to
347c94d
Compare
@@ -2834,6 +2837,13 @@ void SetupProcessObject(Environment* env, | |||
READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate())); | |||
} | |||
|
|||
// --warn-on-sync | |||
if (warn_on_sync) { | |||
READONLY_PROPERTY(process, "warnOnSync", True(env->isolate())); |
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.
It seems weird that this property is always either true or doesn't exist, should it just always be defined as either true or false?
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'm just following the current implementation for all other properties of this type, e.g. process.traceDeprecation
.
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 then
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.
though you're right. a PR to conditionally set those would be fairly trivial. i'll put that on my list, unless you get to it first. :)
LGTM with comments |
347c94d
to
7d1474e
Compare
Cross-linking: #1674 |
Almost forgot, there should be |
7d1474e
to
c6ea43d
Compare
@petkaantonov Good call. Also I analyzed the stack trace formatting that V8 uses and matched it as closely as possible using the available C++ API. I think that will be good enough for now. |
Use the --trace-sync-io flag to print a stack trace whenever a sync method is used after the first tick, excluding during the process exit event. (e.g. fs.readFileSync()) It does not track if the warning has occurred at a specific location in the past and so will print the warning every time. Reason for not printing during the first tick of the appication is so all necessary resources can be required. Also by excluding synchronous calls during exit is necessary in case any data needs to be logged out by the application before it shuts down. Fixes: nodejs#1674 PR-URL: nodejs#1707 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Petka Antonov <[email protected]>
2c715a6
to
dd6f71a
Compare
Use the --trace-sync-io flag to print a stack trace whenever a sync method is used after the first tick, excluding during the process exit event. (e.g. fs.readFileSync()) It does not track if the warning has occurred at a specific location in the past and so will print the warning every time. Reason for not printing during the first tick of the appication is so all necessary resources can be required. Also by excluding synchronous calls during exit is necessary in case any data needs to be logged out by the application before it shuts down. Fixes: nodejs#1674 PR-URL: nodejs#1707 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Petka Antonov <[email protected]>
break; | ||
} | ||
|
||
if (strcmp(*fn_name_s, "") == 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.
I wonder if we could use fn_name_s.length()
here ;)
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.
done.
Use the --trace-sync-io flag to print a stack trace whenever a sync method is used after the first tick, excluding during the process exit event. (e.g. fs.readFileSync()) It does not track if the warning has occurred at a specific location in the past and so will print the warning every time. Reason for not printing during the first tick of the appication is so all necessary resources can be required. Also by excluding synchronous calls during exit is necessary in case any data needs to be logged out by the application before it shuts down. Fixes: nodejs#1674 PR-URL: nodejs#1707 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Petka Antonov <[email protected]>
dd6f71a
to
c1de6d2
Compare
Related to the code conversation - I think the performance of printing the trace is mostly irrelevant anyway @trevnorris - we expect this to log very rarely and never in production anyway. I'm not even sure that it's a bad idea to flush it at every iteration. Don't be so hard on yourself :) Related to the name - are we OK with On an unrelated hook - it might be interesting to find out if there is a need to expose sync io detected events on Good work by the way. |
LGTM |
@benjamingr What I was taking about is that I return if one of the stack trace lines was ever an It does only print after the first "phase" (not "tick" as in @indutny thanks! |
Thanks all. Landed in c1de6d2. |
Nice work, and thanks :) |
@trevnorris seems the new test added here fails on a few platforms: https://jenkins-iojs.nodesource.com/view/iojs/job/iojs+any-pr+multi/686/
|
Tentative fix @ #1734 |
PR-URL: nodejs#1532 Notable Changes: * crypto: Diffie-Hellman key exchange (DHE) parameters ('dhparams') must now be 1024 bits or longer or an error will be thrown. A warning will also be printed to the console if you supply less than 2048 bits. See https://weakdh.org/ for further context on this security concern. (Shigeki Ohtsu) nodejs#1739. * node: A new --trace-sync-io command line flag will print a warning and a stack trace whenever a synchronous API is used. This can be used to track down synchronous calls that may be slowing down an application. (Trevor Norris) nodejs#1707. * node: To allow for chaining of methods, the setTimeout(), setKeepAlive(), setNoDelay(), ref() and unref() methods used in 'net', 'dgram', 'http', 'https' and 'tls' now return the current instance instead of undefined (Roman Reiss) nodejs#1779. * util: A significant speed-up (in the order of 35%) for the common-case of a single string argument to util.format(), used by console.log() (Сковорода Никита Андреевич) nodejs#1749.
PR-URL: nodejs#1532 Notable Changes: * crypto: Diffie-Hellman key exchange (DHE) parameters ('dhparams') must now be 1024 bits or longer or an error will be thrown. A warning will also be printed to the console if you supply less than 2048 bits. See https://weakdh.org/ for further context on this security concern. (Shigeki Ohtsu) nodejs#1739. * node: A new --trace-sync-io command line flag will print a warning and a stack trace whenever a synchronous API is used. This can be used to track down synchronous calls that may be slowing down an application. (Trevor Norris) nodejs#1707. * node: To allow for chaining of methods, the setTimeout(), setKeepAlive(), setNoDelay(), ref() and unref() methods used in 'net', 'dgram', 'http', 'https' and 'tls' now return the current instance instead of undefined (Roman Reiss & Evan Lucas) nodejs#1699 nodejs#1768 nodejs#1779. * util: A significant speed-up (in the order of 35%) for the common-case of a single string argument to util.format(), used by console.log() (Сковорода Никита Андреевич) nodejs#1749.
PR-URL: nodejs#1532 Notable Changes: * crypto: Diffie-Hellman key exchange (DHE) parameters ('dhparams') must now be 1024 bits or longer or an error will be thrown. A warning will also be printed to the console if you supply less than 2048 bits. See https://weakdh.org/ for further context on this security concern. (Shigeki Ohtsu) nodejs#1739. * node: A new --trace-sync-io command line flag will print a warning and a stack trace whenever a synchronous API is used. This can be used to track down synchronous calls that may be slowing down an application. (Trevor Norris) nodejs#1707. * node: To allow for chaining of methods, the setTimeout(), setKeepAlive(), setNoDelay(), ref() and unref() methods used in 'net', 'dgram', 'http', 'https' and 'tls' now return the current instance instead of undefined (Roman Reiss & Evan Lucas) nodejs#1699 nodejs#1768 nodejs#1779. * util: A significant speed-up (in the order of 35%) for the common-case of a single string argument to util.format(), used by console.log() (Сковорода Никита Андреевич) nodejs#1749.
PR-URL: nodejs#1532 Notable Changes: * crypto: Diffie-Hellman key exchange (DHE) parameters ('dhparams') must now be 1024 bits or longer or an error will be thrown. A warning will also be printed to the console if you supply less than 2048 bits. See https://weakdh.org/ for further context on this security concern. (Shigeki Ohtsu) nodejs#1739. * node: A new --trace-sync-io command line flag will print a warning and a stack trace whenever a synchronous API is used. This can be used to track down synchronous calls that may be slowing down an application. (Trevor Norris) nodejs#1707. * node: To allow for chaining of methods, the setTimeout(), setKeepAlive(), setNoDelay(), ref() and unref() methods used in 'net', 'dgram', 'http', 'https' and 'tls' now return the current instance instead of undefined (Roman Reiss & Evan Lucas) nodejs#1699 nodejs#1768 nodejs#1779. * npm: Upgraded to v2.10.1, release notes can be found in https://github.com/npm/npm/releases/tag/v2.10.1 and https://github.com/npm/npm/releases/tag/v2.10.0. * util: A significant speed-up (in the order of 35%) for the common-case of a single string argument to util.format(), used by console.log() (Сковорода Никита Андреевич) nodejs#1749.
PR-URL: #1777 Notable Changes: * crypto: Diffie-Hellman key exchange (DHE) parameters ('dhparams') must now be 1024 bits or longer or an error will be thrown. A warning will also be printed to the console if you supply less than 2048 bits. See https://weakdh.org/ for further context on this security concern. (Shigeki Ohtsu) #1739. * node: A new --trace-sync-io command line flag will print a warning and a stack trace whenever a synchronous API is used. This can be used to track down synchronous calls that may be slowing down an application. (Trevor Norris) #1707. * node: To allow for chaining of methods, the setTimeout(), setKeepAlive(), setNoDelay(), ref() and unref() methods used in 'net', 'dgram', 'http', 'https' and 'tls' now return the current instance instead of undefined (Roman Reiss & Evan Lucas) #1699 #1768 #1779. * npm: Upgraded to v2.10.1, release notes can be found in https://github.com/npm/npm/releases/tag/v2.10.1 and https://github.com/npm/npm/releases/tag/v2.10.0. * util: A significant speed-up (in the order of 35%) for the common-case of a single string argument to util.format(), used by console.log() (Сковорода Никита Андреевич) #1749.
Use the --trace-sync-io flag to print a stack trace whenever a sync method is used after the first tick, excluding during the process exit event. (e.g. fs.readFileSync()) It does not track if the warning has occurred at a specific location in the past and so will print the warning every time. Reason for not printing during the first tick of the appication is so all necessary resources can be required. Also by excluding synchronous calls during exit is necessary in case any data needs to be logged out by the application before it shuts down. Fixes: nodejs/node#1674 PR-URL: nodejs/node#1707 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Petka Antonov <[email protected]>
Use the --warn-on-sync flag to print a stack trace whenever a sync
method is used. (e.g. fs.readFileSync()) It does not track if the
warning has occurred as a specific location in the past and so will
print the warning every time the function is used.
This does not print the warning for the first synchronous execution of
the script. This will allow all the require(), etc. statements to run
that are necessary to prepare the environment.
NOTE: I believe I've addressed all applicable sync calls that should warn the user. I will not be enabling the warning for the
'net'
module's.listen()
calls that exclude the callback. Because the calls are actually synchronous under the hood and we simply queue the callback asynchronously to be run. It also appears to be the same forhttp.{get,request}()
. Also calls to any stream's.write()
are still async even if the callback is excluded.Opening this up now so we can have further discussion.