1

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.

Richard Wheeldon
  • 973
  • 10
  • 25

0 Answers0