Skip to content
This repository was archived by the owner on Jun 18, 2021. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ void Initialize(v8::Local<v8::Object> exports) {

SetLoadTime();
SetVersionString(isolate);
SetCommandLine();

const char* verbose_switch = secure_getenv("NODEREPORT_VERBOSE");
if (verbose_switch != nullptr) {
Expand Down
86 changes: 84 additions & 2 deletions src/node_report.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <dlfcn.h>
#ifndef _AIX
#include <execinfo.h>
#else
#include <sys/procfs.h>
#endif
#include <sys/utsname.h>
#endif
Expand All @@ -41,6 +43,11 @@
#define UNKNOWN_NODEVERSION_STRING "Unable to determine Node.js version\n"
#endif

#ifdef __APPLE__
// Include _NSGetArgv and _NSGetArgc for command line arguments.
#include <crt_externs.h>
#endif

#ifndef _WIN32
extern char** environ;
#endif
Expand All @@ -58,6 +65,7 @@ using v8::String;
using v8::V8;

// Internal/static function declarations
static void PrintCommandLine(FILE* fp);
static void PrintVersionInformation(FILE* fp, Isolate* isolate);
static void PrintJavaScriptStack(FILE* fp, Isolate* isolate, DumpEvent event, const char* location);
static void PrintStackFromStackTrace(FILE* fp, Isolate* isolate, DumpEvent event);
Expand All @@ -77,6 +85,7 @@ static bool report_active = false; // recursion protection
static char report_filename[NR_MAXNAME + 1] = "";
static char report_directory[NR_MAXPATH + 1] = ""; // defaults to current working directory
static std::string version_string = UNKNOWN_NODEVERSION_STRING;
static std::string commandline_string = "";
#ifdef _WIN32
static SYSTEMTIME loadtime_tm_struct; // module load time
#else // UNIX, OSX
Expand Down Expand Up @@ -299,6 +308,65 @@ void SetLoadTime() {
localtime_r(&time_val.tv_sec, &loadtime_tm_struct);
#endif
}

/*******************************************************************************
* Function to save the process command line
*******************************************************************************/
void SetCommandLine() {
#ifdef __linux__
// Read the command line from /proc/self/cmdline
char buf[64];
FILE* cmdline_fd = fopen("/proc/self/cmdline", "r");
if (cmdline_fd == nullptr) {
return;
}
commandline_string = "";
int bytesread = fread(buf, 1, sizeof(buf), cmdline_fd);
while (bytesread > 0) {
for (int i = 0; i < bytesread; i++) {
// Arguments are null separated.
if (buf[i] == '\0') {
commandline_string += " ";
} else {
commandline_string += buf[i];
}
}
bytesread = fread(buf, 1, sizeof(buf), cmdline_fd);
}
fclose(cmdline_fd);
#elif __APPLE__
char **argv = *_NSGetArgv();
int argc = *_NSGetArgc();

commandline_string = "";
std::string seperator = "";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: seperator -> separator

for (int i = 0; i < argc; i++) {
commandline_string += seperator + argv[i];
seperator = " ";
}
#elif _AIX
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation for this #elif block is different from the rest of this function, please can you make it consistent?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rest of the function was wrong and didn't match the file. I'd indented when starting #ifdef sections. I've adjusted the rest of the function to be correct.

// Read the command line from /proc/self/cmdline
char procbuf[64];
snprintf(procbuf, sizeof(procbuf), "/proc/%d/psinfo", getpid());
FILE* psinfo_fd = fopen(procbuf, "r");
if (psinfo_fd == nullptr) {
return;
}
psinfo_t info;
int bytesread = fread(&info, 1, sizeof(psinfo_t), psinfo_fd);
fclose(psinfo_fd);
if (bytesread == sizeof(psinfo_t)) {
commandline_string = "";
std::string seperator = "";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: seperator -> separator

char **argv = *((char ***) info.pr_argv);
for (uint32_t i = 0; i < info.pr_argc; i++) {
commandline_string += seperator + argv[i];
seperator = " ";
}
}
#endif // _AIX
}

/*******************************************************************************
* Main API function to write a NodeReport to file.
*
Expand All @@ -311,7 +379,7 @@ void SetLoadTime() {
******************************************************************************/
void TriggerNodeReport(Isolate* isolate, DumpEvent event, const char* message, const char* location, char* name) {
// Recursion check for NodeReport in progress, bail out
if (report_active) return;
if (report_active) return;
report_active = true;

// Obtain the current time and the pid (platform dependent)
Expand Down Expand Up @@ -414,6 +482,10 @@ void TriggerNodeReport(Isolate* isolate, DumpEvent event, const char* message, c
fprintf(fp, "Process ID: %d\n", pid);
fflush(fp);

// Print out the command line.
PrintCommandLine(fp);
fflush(fp);

// Print Node.js and OS version information
PrintVersionInformation(fp, isolate);
fflush(fp);
Expand Down Expand Up @@ -463,6 +535,16 @@ void TriggerNodeReport(Isolate* isolate, DumpEvent event, const char* message, c
report_active = false;
}

/*******************************************************************************
* Function to print process command line.
*
******************************************************************************/
static void PrintCommandLine(FILE* fp) {
if (commandline_string != "") {
fprintf(fp, "Command line arguments: %s\n", commandline_string.c_str());
}
}

/*******************************************************************************
* Function to print Node.js version, OS version and machine information
*
Expand Down Expand Up @@ -688,7 +770,7 @@ void PrintNativeStack(FILE* fp) {
SymInitialize(hProcess, nullptr, TRUE);

WORD numberOfFrames = CaptureStackBackTrace(2, 64, frames, nullptr);

// Walk the frames printing symbolic information if available
for (int i = 0; i < numberOfFrames; i++) {
DWORD64 dwOffset64 = 0;
Expand Down
1 change: 1 addition & 0 deletions src/node_report.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ unsigned int ProcessNodeReportVerboseSwitch(const char* args);

void SetLoadTime();
void SetVersionString(Isolate* isolate);
void SetCommandLine();

// Local implementation of secure_getenv()
inline const char* secure_getenv(const char* key) {
Expand Down