Can I get a stacktrace from an arbitrary running NodeJS program, preferably without altering the code itself? I can do this trivially for Java but can't seem to find the Node equivalent.
And for reference, I'm not talking about trivially printing the stack when I catch an error or at an point in the code which I already know about. Hence why things like new Error().stack aren't helpful because they presuppose that I have an error and that I already know where the error handling needs to go.
For example, if I have the following Java code:
public class BadCode {
public static void badFunction() {
while (true) {
}
}
public static void naughtyFunction() {
badFunction();
}
public static void main(String[] args) {
naughtyFunction();
}
}
I can run it, see that it's spinning and get a stacktrace by sending it a QUIT signal:
13:44:45:~ $ java BadCode &
[2] 35595
13:44:51:~ $ ps | grep java
35595 pts/1 00:00:05 java
13:44:57:~ $ kill -QUIT 35595
2022-05-06 13:45:03
Full thread dump Java HotSpot(TM) 64-Bit Server VM (17.0.1+12-LTS-39 mixed mode, sharing):
Threads class SMR info:
_java_thread_list=0x00007feac4127960, length=11, elements={
0x00007feac4023fa0, 0x00007feac40e8730, 0x00007feac40e9b10, 0x00007feac41155c0,
0x00007feac4116970, 0x00007feac4117d80, 0x00007feac4119730, 0x00007feac411ac60,
0x00007feac411c0d0, 0x00007feac41233e0, 0x00007feac41269d0
}
"main" #1 prio=5 os_prio=0 cpu=12616.32ms elapsed=12.64s tid=0x00007feac4023fa0 nid=0x8b0e runnable [0x00007feac97b9000]
java.lang.Thread.State: RUNNABLE
at BadCode.badFunction(BadCode.java:3)
at BadCode.naughtyFunction(BadCode.java:8)
at BadCode.main(BadCode.java:12)
"Reference Handler" #2 daemon prio=10 os_prio=0 cpu=0.19ms elapsed=12.62s tid=0x00007feac40e8730 nid=0x8b16 waiting on condition [0x00007feaa84ef000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@17.0.1/Native Method)
<snip lots more lines of info>
If I have a node equivalent:
function badFunction() {
while (true) {}
}
function naughtyFunction() {
badFunction();
}
naughtyFunction();
I can run it in the same way:
14:05:00:~ $ node badcode.js &
[3] 35759
14:05:02:~ $ ps | grep -i node
35759 pts/1 00:00:02 node
14:05:05:~ $
But now what? How do I know where it's stuck?
Note that in this example it's clearly broken but there's no error to catch, no log message, etc.