1
1
#include < cerrno>
2
2
#include < cstdarg>
3
3
4
+ #include " debug_utils-inl.h"
4
5
#include " node_errors.h"
5
6
#include " node_internals.h"
6
7
#ifdef NODE_REPORT
10
11
#include " node_v8_platform-inl.h"
11
12
#include " util-inl.h"
12
13
13
- #ifdef __ANDROID__
14
- #include < android/log.h>
15
- #endif
16
-
17
14
namespace node {
18
15
19
16
using errors::TryCatchScope;
@@ -54,8 +51,6 @@ namespace per_process {
54
51
static Mutex tty_mutex;
55
52
} // namespace per_process
56
53
57
- static const int kMaxErrorSourceLength = 1024 ;
58
-
59
54
static std::string GetErrorSource (Isolate* isolate,
60
55
Local<Context> context,
61
56
Local<Message> message,
@@ -107,41 +102,35 @@ static std::string GetErrorSource(Isolate* isolate,
107
102
end -= script_start;
108
103
}
109
104
110
- int max_off = kMaxErrorSourceLength - 2 ;
111
-
112
- char buf[kMaxErrorSourceLength ];
113
- int off = snprintf (buf,
114
- kMaxErrorSourceLength ,
115
- " %s:%i\n %s\n " ,
116
- filename_string,
117
- linenum,
118
- sourceline.c_str ());
119
- CHECK_GE (off, 0 );
120
- if (off > max_off) {
121
- off = max_off;
122
- }
105
+ std::string buf = SPrintF (" %s:%i\n %s\n " ,
106
+ filename_string,
107
+ linenum,
108
+ sourceline.c_str ());
109
+ CHECK_GT (buf.size (), 0 );
123
110
111
+ constexpr int kUnderlineBufsize = 1020 ;
112
+ char underline_buf[kUnderlineBufsize + 4 ];
113
+ int off = 0 ;
124
114
// Print wavy underline (GetUnderline is deprecated).
125
115
for (int i = 0 ; i < start; i++) {
126
- if (sourceline[i] == ' \0 ' || off >= max_off ) {
116
+ if (sourceline[i] == ' \0 ' || off >= kUnderlineBufsize ) {
127
117
break ;
128
118
}
129
- CHECK_LT (off, max_off );
130
- buf [off++] = (sourceline[i] == ' \t ' ) ? ' \t ' : ' ' ;
119
+ CHECK_LT (off, kUnderlineBufsize );
120
+ underline_buf [off++] = (sourceline[i] == ' \t ' ) ? ' \t ' : ' ' ;
131
121
}
132
122
for (int i = start; i < end; i++) {
133
- if (sourceline[i] == ' \0 ' || off >= max_off ) {
123
+ if (sourceline[i] == ' \0 ' || off >= kUnderlineBufsize ) {
134
124
break ;
135
125
}
136
- CHECK_LT (off, max_off );
137
- buf [off++] = ' ^' ;
126
+ CHECK_LT (off, kUnderlineBufsize );
127
+ underline_buf [off++] = ' ^' ;
138
128
}
139
- CHECK_LE (off, max_off);
140
- buf[off] = ' \n ' ;
141
- buf[off + 1 ] = ' \0 ' ;
129
+ CHECK_LE (off, kUnderlineBufsize );
130
+ underline_buf[off++] = ' \n ' ;
142
131
143
132
*added_exception_line = true ;
144
- return std::string (buf );
133
+ return buf + std::string (underline_buf, off );
145
134
}
146
135
147
136
void PrintStackTrace (Isolate* isolate, Local<StackTrace> stack) {
@@ -154,9 +143,9 @@ void PrintStackTrace(Isolate* isolate, Local<StackTrace> stack) {
154
143
155
144
if (stack_frame->IsEval ()) {
156
145
if (stack_frame->GetScriptId () == Message::kNoScriptIdInfo ) {
157
- fprintf (stderr, " at [eval]:%i:%i\n " , line_number, column);
146
+ FPrintF (stderr, " at [eval]:%i:%i\n " , line_number, column);
158
147
} else {
159
- fprintf (stderr,
148
+ FPrintF (stderr,
160
149
" at [eval] (%s:%i:%i)\n " ,
161
150
*script_name,
162
151
line_number,
@@ -166,12 +155,12 @@ void PrintStackTrace(Isolate* isolate, Local<StackTrace> stack) {
166
155
}
167
156
168
157
if (fn_name_s.length () == 0 ) {
169
- fprintf (stderr, " at %s:%i:%i\n " , * script_name, line_number, column);
158
+ FPrintF (stderr, " at %s:%i:%i\n " , script_name, line_number, column);
170
159
} else {
171
- fprintf (stderr,
160
+ FPrintF (stderr,
172
161
" at %s (%s:%i:%i)\n " ,
173
- * fn_name_s,
174
- * script_name,
162
+ fn_name_s,
163
+ script_name,
175
164
line_number,
176
165
column);
177
166
}
@@ -189,8 +178,8 @@ void PrintException(Isolate* isolate,
189
178
bool added_exception_line = false ;
190
179
std::string source =
191
180
GetErrorSource (isolate, context, message, &added_exception_line);
192
- fprintf (stderr, " %s\n " , source. c_str () );
193
- fprintf (stderr, " %s\n " , * reason);
181
+ FPrintF (stderr, " %s\n " , source);
182
+ FPrintF (stderr, " %s\n " , reason);
194
183
195
184
Local<v8::StackTrace> stack = message->GetStackTrace ();
196
185
if (!stack.IsEmpty ()) PrintStackTrace (isolate, stack);
@@ -235,7 +224,7 @@ void AppendExceptionLine(Environment* env,
235
224
env->set_printed_error (true );
236
225
237
226
ResetStdio ();
238
- PrintErrorString ( " \n %s" , source. c_str () );
227
+ FPrintF (stderr, " \n %s" , source);
239
228
return ;
240
229
}
241
230
@@ -347,10 +336,10 @@ static void ReportFatalException(Environment* env,
347
336
// range errors have a trace member set to undefined
348
337
if (trace.length () > 0 && !stack_trace->IsUndefined ()) {
349
338
if (arrow.IsEmpty () || !arrow->IsString () || decorated) {
350
- PrintErrorString ( " %s\n " , * trace);
339
+ FPrintF (stderr, " %s\n " , trace);
351
340
} else {
352
341
node::Utf8Value arrow_string (env->isolate (), arrow);
353
- PrintErrorString ( " %s\n %s\n " , * arrow_string, * trace);
342
+ FPrintF (stderr, " %s\n %s\n " , arrow_string, trace);
354
343
}
355
344
} else {
356
345
// this really only happens for RangeErrors, since they're the only
@@ -368,76 +357,40 @@ static void ReportFatalException(Environment* env,
368
357
if (message.IsEmpty () || message.ToLocalChecked ()->IsUndefined () ||
369
358
name.IsEmpty () || name.ToLocalChecked ()->IsUndefined ()) {
370
359
// Not an error object. Just print as-is.
371
- String ::Utf8Value message (env->isolate (), error);
360
+ node ::Utf8Value message (env->isolate (), error);
372
361
373
- PrintErrorString ( " %s\n " ,
374
- *message ? * message : " <toString() threw exception>" );
362
+ FPrintF (stderr, " %s\n " ,
363
+ *message ? message. ToString () : " <toString() threw exception>" );
375
364
} else {
376
365
node::Utf8Value name_string (env->isolate (), name.ToLocalChecked ());
377
366
node::Utf8Value message_string (env->isolate (), message.ToLocalChecked ());
378
367
379
368
if (arrow.IsEmpty () || !arrow->IsString () || decorated) {
380
- PrintErrorString ( " %s: %s\n " , * name_string, * message_string);
369
+ FPrintF (stderr, " %s: %s\n " , name_string, message_string);
381
370
} else {
382
371
node::Utf8Value arrow_string (env->isolate (), arrow);
383
- PrintErrorString (
384
- " %s\n %s: %s\n " , * arrow_string, * name_string, * message_string);
372
+ FPrintF (stderr,
373
+ " %s\n %s: %s\n " , arrow_string, name_string, message_string);
385
374
}
386
375
}
387
376
388
377
if (!env->options ()->trace_uncaught ) {
389
- PrintErrorString ( " (Use `node --trace-uncaught ...` to show "
390
- " where the exception was thrown)\n " );
378
+ FPrintF (stderr, " (Use `node --trace-uncaught ...` to show "
379
+ " where the exception was thrown)\n " );
391
380
}
392
381
}
393
382
394
383
if (env->options ()->trace_uncaught ) {
395
384
Local<StackTrace> trace = message->GetStackTrace ();
396
385
if (!trace.IsEmpty ()) {
397
- PrintErrorString ( " Thrown at:\n " );
386
+ FPrintF (stderr, " Thrown at:\n " );
398
387
PrintStackTrace (env->isolate (), trace);
399
388
}
400
389
}
401
390
402
391
fflush (stderr);
403
392
}
404
393
405
- void PrintErrorString (const char * format, ...) {
406
- va_list ap;
407
- va_start (ap, format);
408
- #ifdef _WIN32
409
- HANDLE stderr_handle = GetStdHandle (STD_ERROR_HANDLE);
410
-
411
- // Check if stderr is something other than a tty/console
412
- if (stderr_handle == INVALID_HANDLE_VALUE || stderr_handle == nullptr ||
413
- uv_guess_handle (_fileno (stderr)) != UV_TTY) {
414
- vfprintf (stderr, format, ap);
415
- va_end (ap);
416
- return ;
417
- }
418
-
419
- // Fill in any placeholders
420
- int n = _vscprintf (format, ap);
421
- std::vector<char > out (n + 1 );
422
- vsprintf (out.data (), format, ap);
423
-
424
- // Get required wide buffer size
425
- n = MultiByteToWideChar (CP_UTF8, 0 , out.data (), -1 , nullptr , 0 );
426
-
427
- std::vector<wchar_t > wbuf (n);
428
- MultiByteToWideChar (CP_UTF8, 0 , out.data (), -1 , wbuf.data (), n);
429
-
430
- // Don't include the null character in the output
431
- CHECK_GT (n, 0 );
432
- WriteConsoleW (stderr_handle, wbuf.data (), n - 1 , nullptr , nullptr );
433
- #elif defined(__ANDROID__)
434
- __android_log_vprint (ANDROID_LOG_ERROR, " nodejs" , format, ap);
435
- #else
436
- vfprintf (stderr, format, ap);
437
- #endif
438
- va_end (ap);
439
- }
440
-
441
394
[[noreturn]] void FatalError (const char * location, const char * message) {
442
395
OnFatalError (location, message);
443
396
// to suppress compiler warning
@@ -446,9 +399,9 @@ void PrintErrorString(const char* format, ...) {
446
399
447
400
void OnFatalError (const char * location, const char * message) {
448
401
if (location) {
449
- PrintErrorString ( " FATAL ERROR: %s %s\n " , location, message);
402
+ FPrintF (stderr, " FATAL ERROR: %s %s\n " , location, message);
450
403
} else {
451
- PrintErrorString ( " FATAL ERROR: %s\n " , message);
404
+ FPrintF (stderr, " FATAL ERROR: %s\n " , message);
452
405
}
453
406
#ifdef NODE_REPORT
454
407
Isolate* isolate = Isolate::GetCurrent ();
0 commit comments