The command line arguments to the node process seem to be becoming corrupted on AIX when displayed by the ps command. For example if I run a simple script and use a command line option:
> node --abort_on_uncaught_exception --experimental_extras --max_old_space_size=300 --no-warnings simplehttp.js opt1 opt2 opt3
The output of running the ps command is:
[hhellyer@dhcp-9-20-187-94 nodereport.git]$ ps -f 3654
UID PID PPID C STIME TTY TIME CMD
hhellyer 16187482 7274616 1 10:18:00 pts/0 0:00 node simplehttp.js opt1 opt2 opt3 simplehttp.js opt1 opt2 opt3
It looks like the script name and arguments have moved up but not cleared from their original position. It doesn鈥檛 seem to be specific to using v8 arguments beginning with --, using -r to require a module causes the same problem.
If I run the same script with the same options on Linux or Mac the output from ps is correct. e.g from Linux:
UID PID PPID C STIME TTY TIME CMD
hhellyer 10015 2888 0 15:19 pts/9 00:00:00 node --abort_on_uncaught_exception --experimental_extras --max_old_space_size=300 --no-warnings simplehttp.js opt1 opt2 opt3
which is exactly what was on the command line. On AIX if I run a script that prints process.argv and process.execArgv with the same options they are in in the correct positions, it's only the output from ps that looks wrong. It may be something specific in how the options are handled on AIX or it may be node always corrupts argv but that AIX is the only platform that gives the process the real argv array that鈥檚 also used by the ps command.
@nodejs/platform-aix - Probably worth the AIX team looking at this in the first instance however it may be a more general problem.
Node modifies the argv array in src/node.cc stripping off all the options leaving only the script file and parameters.
The "ps" utility regenerates the command line options from the modified argv but using the same original argc value. It seems like on other platforms, the "ps" utility does not regenerate from argv but from a cache where the original options were stored.
After a quick google and a test it looks like caching isn鈥檛 quite what鈥檚 happening.
It looks like on Linux and Mac the command line arguments are in a memory, starting at the address of the first string (argv[0]) and separated by nulls. If you want to change the command line ps shows then on Mac and Linux you need to actually overwrite the contents of the original strings. Changing the pointers in the argv array won鈥檛 do it - the strings themselves need to change.
Assuming Node doesn鈥檛 intend to hide v8 arguments from ps then this bug only affects AIX. (If Node did intend to change the ps output then I suspect that fixing that now might break a surprising number of things that read the ps output - monitoring scripts and the like.) Either way it should probably just be fixed for AIX so that AIX is consistent with the behaviour on other platforms and doesn鈥檛 display junk.
If I can sort my AIX build environment out I鈥檒l have a look at copying argv to a new array the startup code can safely modify but it should be a fairly trivial fix.
I've prototyped the change to libuv on a branch in my node repository, now I need to clone libuv, test the change there on AIX and raise the pull request against libuv. If anyone is interested the change is here:
https://github.com/hhellyer/node/tree/uv_cmdline_aix
The pull request for libuv https://github.com/libuv/libuv/pull/1187 has been approved. I will close the PR for duplicating argv on AIX (https://github.com/nodejs/node/pull/10633).
I think I need to raise another PR to enable the test for setting process.title (test/simple/test-setproctitle.js) on AIX once that change has been committed into libuv and Node has taken that level of libuv. It's a very small change but is there a way to tag that so it doesn't get lost?
I think I need to raise another PR to enable the test for setting process.title (test/simple/test-setproctitle.js) on AIX once that change has been committed into libuv and Node has taken that level of libuv. It's a very small change but is there a way to tag that so it doesn't get lost?
@hhellyer Time to raise this PR?
@gibfahn - Yes, I'll change it to match the libuv test which now only skips the test for SunOS. The libuv update also enabled setting the process title on MVS and now the libuv runs for everything except SunOS. (I just need to try the test out in those two environments first.)
Change for enabling the test in Node.js raised as PR #11416