Skip to content

Commit 19e77d3

Browse files
committed
core: implement runtime flag to pring warn on sync
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 warnings for the first iteration of the event loop.
1 parent 4e2f999 commit 19e77d3

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

src/node.cc

+31
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ using v8::Promise;
102102
using v8::PromiseRejectMessage;
103103
using v8::PropertyCallbackInfo;
104104
using v8::SealHandleScope;
105+
using v8::StackFrame;
106+
using v8::StackTrace;
105107
using v8::String;
106108
using v8::TryCatch;
107109
using v8::Uint32;
@@ -113,6 +115,7 @@ static bool print_eval = false;
113115
static bool force_repl = false;
114116
static bool trace_deprecation = false;
115117
static bool throw_deprecation = false;
118+
static bool warn_on_sync = false;
116119
static bool abort_on_uncaught_exception = false;
117120
static const char* eval_string = nullptr;
118121
static unsigned int preload_module_count = 0;
@@ -1492,6 +1495,27 @@ static void ReportException(Environment* env, const TryCatch& try_catch) {
14921495
}
14931496

14941497

1498+
void PrintSyncWarning(Environment* env) {
1499+
if (!warn_on_sync)
1500+
return;
1501+
1502+
Isolate* isolate = env->isolate();
1503+
HandleScope handle_scope(isolate);
1504+
Local<StackTrace> stack = StackTrace::CurrentStackTrace(
1505+
isolate, 10, StackTrace::kDetailed);
1506+
1507+
fprintf(stderr, "WARNING: Detected use of sync API\n");
1508+
for (int i = 0; i < stack->GetFrameCount() - 1; i++) {
1509+
Local<StackFrame> sf = stack->GetFrame(i);
1510+
node::Utf8Value n(isolate, sf->GetFunctionName());
1511+
node::Utf8Value m(isolate, sf->GetScriptName());
1512+
int ln = sf->GetLineNumber();
1513+
int cl = sf->GetColumn();
1514+
fprintf(stderr, " at %s (%s:%i:%i)\n", *n, *m, ln, cl);
1515+
}
1516+
}
1517+
1518+
14951519
// Executes a str within the current v8 context.
14961520
static Local<Value> ExecuteString(Environment* env,
14971521
Handle<String> source,
@@ -2834,6 +2858,11 @@ void SetupProcessObject(Environment* env,
28342858
READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate()));
28352859
}
28362860

2861+
// --warn-on-sync
2862+
if (warn_on_sync) {
2863+
READONLY_PROPERTY(process, "printOnSync", True(env->isolate()));
2864+
}
2865+
28372866
size_t exec_path_len = 2 * PATH_MAX;
28382867
char* exec_path = new char[exec_path_len];
28392868
Local<String> exec_path_value;
@@ -3180,6 +3209,8 @@ static void ParseArgs(int* argc,
31803209
no_deprecation = true;
31813210
} else if (strcmp(arg, "--trace-deprecation") == 0) {
31823211
trace_deprecation = true;
3212+
} else if (strcmp(arg, "--warn-on-sync") == 0) {
3213+
warn_on_sync = true;
31833214
} else if (strcmp(arg, "--throw-deprecation") == 0) {
31843215
throw_deprecation = true;
31853216
} else if (strcmp(arg, "--abort-on-uncaught-exception") == 0 ||

src/node.h

+3
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,9 @@ NODE_DEPRECATED("Use DecodeWrite(isolate, ...)",
335335
return DecodeWrite(v8::Isolate::GetCurrent(), buf, buflen, val, encoding);
336336
})
337337

338+
339+
void PrintSyncWarning(Environment* env);
340+
338341
#ifdef _WIN32
339342
NODE_EXTERN v8::Local<v8::Value> WinapiErrnoException(
340343
v8::Isolate* isolate,

src/node_crypto.cc

+2
Original file line numberDiff line numberDiff line change
@@ -4630,6 +4630,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
46304630
EIO_PBKDF2,
46314631
EIO_PBKDF2After);
46324632
} else {
4633+
PrintSyncWarning(env);
46334634
Local<Value> argv[2];
46344635
EIO_PBKDF2(req);
46354636
EIO_PBKDF2After(req, argv);
@@ -4786,6 +4787,7 @@ void RandomBytes(const FunctionCallbackInfo<Value>& args) {
47864787
RandomBytesAfter);
47874788
args.GetReturnValue().Set(obj);
47884789
} else {
4790+
PrintSyncWarning(env);
47894791
Local<Value> argv[2];
47904792
RandomBytesWork(req->work_req());
47914793
RandomBytesCheck(req, argv);

src/node_file.cc

+1
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ struct fs_req_wrap {
280280

281281
#define SYNC_DEST_CALL(func, path, dest, ...) \
282282
fs_req_wrap req_wrap; \
283+
PrintSyncWarning(env); \
283284
int err = uv_fs_ ## func(env->event_loop(), \
284285
&req_wrap.req, \
285286
__VA_ARGS__, \

src/spawn_sync.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,9 @@ void SyncProcessRunner::Initialize(Handle<Object> target,
349349

350350

351351
void SyncProcessRunner::Spawn(const FunctionCallbackInfo<Value>& args) {
352-
SyncProcessRunner p(Environment::GetCurrent(args));
352+
Environment* env = Environment::GetCurrent(args);
353+
PrintSyncWarning(env);
354+
SyncProcessRunner p(env);
353355
Local<Value> result = p.Run(args[0]);
354356
args.GetReturnValue().Set(result);
355357
}

0 commit comments

Comments
 (0)