1
1
#include " node_report.h"
2
- #include " node_version.h"
3
2
#include " v8.h"
4
3
#include " time.h"
5
- #include " zlib.h"
6
- #include " ares.h"
7
4
8
5
#include < fcntl.h>
6
+ #include < map>
9
7
#include < string.h>
10
8
#include < stdio.h>
11
9
#include < stdlib.h>
35
33
#include < sys/utsname.h>
36
34
#endif
37
35
36
+ #if !defined(NODEREPORT_VERSION)
37
+ #define NODEREPORT_VERSION " dev"
38
+ #endif
39
+
40
+ #if !defined(UNKNOWN_NODEVERSION_STRING)
41
+ #define UNKNOWN_NODEVERSION_STRING " Unable to determine Node.js version\n "
42
+ #endif
43
+
38
44
#ifndef _WIN32
39
45
extern char ** environ;
40
46
#endif
@@ -52,7 +58,7 @@ using v8::String;
52
58
using v8::V8;
53
59
54
60
// Internal/static function declarations
55
- static void PrintVersionInformation (FILE* fp);
61
+ static void PrintVersionInformation (FILE* fp, Isolate* isolate );
56
62
static void PrintJavaScriptStack (FILE* fp, Isolate* isolate, DumpEvent event, const char * location);
57
63
static void PrintStackFromStackTrace (FILE* fp, Isolate* isolate, DumpEvent event);
58
64
static void PrintStackFrame (FILE* fp, Isolate* isolate, Local<StackFrame> frame, int index, void * pc);
@@ -70,6 +76,7 @@ const char* v8_states[] = {"JS", "GC", "COMPILER", "OTHER", "EXTERNAL", "IDLE"};
70
76
static bool report_active = false ; // recursion protection
71
77
static char report_filename[NR_MAXNAME + 1 ] = " " ;
72
78
static char report_directory[NR_MAXPATH + 1 ] = " " ; // defaults to current working directory
79
+ static std::string version_string = UNKNOWN_NODEVERSION_STRING;
73
80
#ifdef _WIN32
74
81
static SYSTEMTIME loadtime_tm_struct; // module load time
75
82
#else // UNIX, OSX
@@ -189,6 +196,97 @@ unsigned int ProcessNodeReportVerboseSwitch(const char* args) {
189
196
return 0 ; // Default is verbose mode off
190
197
}
191
198
199
+ void SetVersionString (Isolate* isolate) {
200
+ // Catch anything thrown and gracefully return
201
+ Nan::TryCatch trycatch;
202
+ version_string = UNKNOWN_NODEVERSION_STRING;
203
+
204
+ // Retrieve the process object
205
+ v8::Local<v8::String> process_prop;
206
+ if (!Nan::New<v8::String>(" process" ).ToLocal (&process_prop)) return ;
207
+ v8::Local<v8::Object> global_obj = isolate->GetCurrentContext ()->Global ();
208
+ v8::Local<v8::Value> process_value;
209
+ if (!Nan::Get (global_obj, process_prop).ToLocal (&process_value)) return ;
210
+ if (!process_value->IsObject ()) return ;
211
+ v8::Local<v8::Object> process_obj = process_value.As <v8::Object>();
212
+
213
+ // Get process.version
214
+ v8::Local<v8::String> version_prop;
215
+ if (!Nan::New<v8::String>(" version" ).ToLocal (&version_prop)) return ;
216
+ v8::Local<v8::Value> version;
217
+ if (!Nan::Get (process_obj, version_prop).ToLocal (&version)) return ;
218
+
219
+ // e.g. Node.js version: v6.9.1
220
+ if (version->IsString ()) {
221
+ Nan::Utf8String node_version (version);
222
+ version_string = " Node.js version: " ;
223
+ version_string += *node_version;
224
+ version_string += " \n " ;
225
+ }
226
+
227
+ // Get process.versions
228
+ v8::Local<v8::String> versions_prop;
229
+ if (!Nan::New<v8::String>(" versions" ).ToLocal (&versions_prop)) return ;
230
+ v8::Local<v8::Value> versions_value;
231
+ if (!Nan::Get (process_obj, versions_prop).ToLocal (&versions_value)) return ;
232
+ if (!versions_value->IsObject ()) return ;
233
+ v8::Local<v8::Object> versions_obj = versions_value.As <v8::Object>();
234
+
235
+ // Get component names and versions from process.versions
236
+ v8::Local<v8::Array> components;
237
+ if (!Nan::GetOwnPropertyNames (versions_obj).ToLocal (&components)) return ;
238
+ v8::Local<v8::Object> components_obj = components.As <v8::Object>();
239
+ std::map<std::string, std::string> comp_versions;
240
+ uint32_t total_components = (*components)->Length ();
241
+ for (uint32_t i = 0 ; i < total_components; i++) {
242
+ v8::Local<v8::Value> name_value;
243
+ if (!Nan::Get (components_obj, i).ToLocal (&name_value)) continue ;
244
+ v8::Local<v8::Value> version_value;
245
+ if (!Nan::Get (versions_obj, name_value).ToLocal (&version_value)) continue ;
246
+
247
+ Nan::Utf8String component_name (name_value);
248
+ Nan::Utf8String component_version (version_value);
249
+ if (*component_name == nullptr || *component_version == nullptr ) continue ;
250
+
251
+ // Don't duplicate the Node.js version
252
+ if (!strcmp (" node" , *component_name)) {
253
+ if (version_string == UNKNOWN_NODEVERSION_STRING) {
254
+ version_string = " Node.js version: v" ;
255
+ version_string += *component_version;
256
+ version_string += " \n " ;
257
+ }
258
+ } else {
259
+ comp_versions[*component_name] = *component_version;
260
+ }
261
+ }
262
+
263
+ // Format sorted component versions surrounded by (), wrapped
264
+ // e.g.
265
+ // (ares: 1.10.1-DEV, http_parser: 2.7.0, icu: 57.1, modules: 48,
266
+ // openssl: 1.0.2j, uv: 1.9.1, v8: 5.1.281.84, zlib: 1.2.8)
267
+ const size_t wrap = 80 ;
268
+ size_t line_length = 1 ;
269
+ version_string += " (" ;
270
+ for (auto it : comp_versions) {
271
+ std::string component_name = it.first ;
272
+ std::string component_version = it.second ;
273
+ size_t length = component_name.length () + component_version.length () + 2 ;
274
+ if (line_length + length + 1 >= wrap) {
275
+ version_string += " \n " ;
276
+ line_length = 1 ;
277
+ }
278
+ version_string += component_name;
279
+ version_string += " : " ;
280
+ version_string += component_version;
281
+ line_length += length;
282
+ if (it != *std::prev (comp_versions.end ())) {
283
+ version_string += " , " ;
284
+ line_length += 2 ;
285
+ }
286
+ }
287
+ version_string += " )\n " ;
288
+ }
289
+
192
290
/* ******************************************************************************
193
291
* Function to save the nodereport module load time value
194
292
*******************************************************************************/
@@ -317,7 +415,7 @@ void TriggerNodeReport(Isolate* isolate, DumpEvent event, const char* message, c
317
415
fflush (fp);
318
416
319
417
// Print Node.js and OS version information
320
- PrintVersionInformation (fp);
418
+ PrintVersionInformation (fp, isolate );
321
419
fflush (fp);
322
420
323
421
// Print summary JavaScript stack backtrace
@@ -369,12 +467,15 @@ void TriggerNodeReport(Isolate* isolate, DumpEvent event, const char* message, c
369
467
* Function to print Node.js version, OS version and machine information
370
468
*
371
469
******************************************************************************/
372
- static void PrintVersionInformation (FILE* fp) {
470
+ static void PrintVersionInformation (FILE* fp, Isolate* isolate ) {
373
471
374
472
// Print Node.js and deps component versions
375
- fprintf (fp, " \n Node.js version: %s\n " , NODE_VERSION);
376
- fprintf (fp, " (v8: %s, libuv: %s, zlib: %s, ares: %s)\n " ,
377
- V8::GetVersion (), uv_version_string (), ZLIB_VERSION, ARES_VERSION_STR);
473
+ fprintf (fp, " \n %s" , version_string.c_str ());
474
+
475
+ // Print NodeReport version
476
+ // e.g. NodeReport version: 1.0.6 (built against Node.js v6.9.1)
477
+ fprintf (fp, " \n NodeReport version: %s (built against Node.js v%s)\n " ,
478
+ NODEREPORT_VERSION, NODE_VERSION_STRING);
378
479
379
480
// Print operating system and machine information (Windows)
380
481
#ifdef _WIN32
0 commit comments