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>
9
6
#include < string.h>
10
7
#include < stdio.h>
11
8
#include < stdlib.h>
9
+ #include < vector>
12
10
13
11
#if !defined(_MSC_VER)
14
12
#include < strings.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,96 @@ 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
+ v8::Local<v8::Object> process_obj = process_value.As <v8::Object>();
211
+
212
+ // Get process.version
213
+ v8::Local<v8::String> version_prop;
214
+ if (!Nan::New<v8::String>(" version" ).ToLocal (&version_prop)) return ;
215
+ v8::Local<v8::Value> version;
216
+ if (!Nan::Get (process_obj, version_prop).ToLocal (&version)) return ;
217
+
218
+ // e.g. Node.js version: v6.9.1
219
+ if (version->IsString ()) {
220
+ Nan::Utf8String node_version (version);
221
+ version_string = " Node.js version: " ;
222
+ version_string += *node_version;
223
+ version_string += " \n " ;
224
+ }
225
+
226
+ // Get process.versions
227
+ v8::Local<v8::String> versions_prop;
228
+ if (!Nan::New<v8::String>(" versions" ).ToLocal (&versions_prop)) return ;
229
+ v8::Local<v8::Value> versions_value;
230
+ if (!Nan::Get (process_obj, versions_prop).ToLocal (&versions_value)) return ;
231
+ if (!versions_value->IsObject ()) return ;
232
+ v8::Local<v8::Object> versions_obj = versions_value.As <v8::Object>();
233
+
234
+ // Get component names and versions from process.versions
235
+ v8::Local<v8::Array> components;
236
+ if (!Nan::GetOwnPropertyNames (versions_obj).ToLocal (&components)) return ;
237
+ v8::Local<v8::Object> components_obj = components.As <v8::Object>();
238
+ uint32_t total_components = (*components)->Length ();
239
+ std::vector<std::string> comp_versions;
240
+ comp_versions.reserve (total_components);
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
+
250
+ // Don't duplicate the Node.js version
251
+ if (!strcmp (" node" , *component_name)) {
252
+ if (version_string == UNKNOWN_NODEVERSION_STRING) {
253
+ version_string = " Node.js version: v" ;
254
+ version_string += *component_version;
255
+ version_string += " \n " ;
256
+ }
257
+ } else {
258
+ std::string component_version_string (*component_name);
259
+ component_version_string += " : " ;
260
+ component_version_string += *component_version;
261
+ comp_versions.push_back (component_version_string);
262
+ }
263
+ }
264
+
265
+ // Format sorted component versions surrounded by (), wrapped
266
+ // e.g.
267
+ // (ares: 1.10.1-DEV, http_parser: 2.7.0, icu: 57.1, modules: 48,
268
+ // openssl: 1.0.2j, uv: 1.9.1, v8: 5.1.281.84, zlib: 1.2.8)
269
+ const size_t wrap = 80 ;
270
+ size_t line_length = 1 ;
271
+ version_string += " (" ;
272
+ std::sort (comp_versions.begin (), comp_versions.end ());
273
+ for (auto it = comp_versions.begin (); it != comp_versions.end (); ++it) {
274
+ size_t length = (*it).length ();
275
+ if (line_length + length + 1 >= wrap) {
276
+ version_string += " \n " ;
277
+ line_length = 1 ;
278
+ }
279
+ version_string += *it;
280
+ line_length += length;
281
+ if (it + 1 != comp_versions.end ()) {
282
+ version_string += " , " ;
283
+ line_length += 2 ;
284
+ }
285
+ }
286
+ version_string += " )\n " ;
287
+ }
288
+
192
289
/* ******************************************************************************
193
290
* Function to save the nodereport module load time value
194
291
*******************************************************************************/
@@ -317,7 +414,7 @@ void TriggerNodeReport(Isolate* isolate, DumpEvent event, const char* message, c
317
414
fflush (fp);
318
415
319
416
// Print Node.js and OS version information
320
- PrintVersionInformation (fp);
417
+ PrintVersionInformation (fp, isolate );
321
418
fflush (fp);
322
419
323
420
// Print summary JavaScript stack backtrace
@@ -369,12 +466,15 @@ void TriggerNodeReport(Isolate* isolate, DumpEvent event, const char* message, c
369
466
* Function to print Node.js version, OS version and machine information
370
467
*
371
468
******************************************************************************/
372
- static void PrintVersionInformation (FILE* fp) {
469
+ static void PrintVersionInformation (FILE* fp, Isolate* isolate ) {
373
470
374
471
// 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);
472
+ fprintf (fp, " \n %s" , version_string.c_str ());
473
+
474
+ // Print NodeReport version
475
+ // e.g. NodeReport version: 1.0.6 (built against Node.js v6.9.1)
476
+ fprintf (fp, " \n NodeReport version: %s (built against Node.js v%s)\n " ,
477
+ NODEREPORT_VERSION, NODE_VERSION_STRING);
378
478
379
479
// Print operating system and machine information (Windows)
380
480
#ifdef _WIN32
0 commit comments