0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00
nodejs/doc/guides/node-postmortem-support.md
Matheus Marchini 756a34e863
src, test: node internals' postmortem metadata
Before these changes, only V8 added postmortem metadata to Node's
binary, limiting the possibilities for debugger's developers to add some
features that rely on investigating Node's internal structures.

These changes are first steps towards empowering debug tools to
navigate Node's internal structures. One example of what can be
achieved with this is shown at nodejs/llnode#122 (a command which prints
information about handles and requests on the queue for a core dump
file). Node postmortem metadata are prefixed with nodedbg_.

This also adds tests to validate if all postmortem metadata are
calculated correctly, plus some documentation on what is postmortem
metadata and a few care to be taken to avoid breaking it.

Ref: https://github.com/nodejs/llnode/pull/122
Ref: https://github.com/nodejs/post-mortem/issues/46

PR-URL: https://github.com/nodejs/node/pull/14901
Refs: https://github.com/nodejs/post-mortem/issues/46
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2018-01-26 08:55:36 +08:00

2.5 KiB

Postmortem Support

Postmortem metadata are constants present in the final build which can be used by debuggers and other tools to navigate through internal structures of software when analyzing its memory (either on a running process or a core dump). Node provides this metadata in its builds for V8 and Node internal structures.

V8 Postmortem metadata

V8 prefixes all postmortem constants with v8dbg_, and they allow inspection of objects on the heap as well as object properties and references. V8 generates those symbols with a script (deps/v8/tools/gen-postmortem-metadata.py), and Node always includes these constants in the final build.

Node Debug Symbols

Node prefixes all postmortem constants with nodedbg_, and they complement V8 constants by providing ways to inspect Node-specific structures, like node::Environment, node::BaseObject and its descendants, classes from src/utils.h and others. Those constants are declared in src/node_postmortem_metadata.cc, and most of them are calculated at compile time.

Calculating offset of class members

Node constants referring to the offset of class members in memory are calculated at compile time. Because of that, those class members must be at a fixed offset from the start of the class. That's not a problem in most cases, but it also means that those members should always come after any templated member on the class definition.

For example, if we want to add a constant with the offset for ReqWrap::req_wrap_queue_, it should be defined after ReqWrap::req_, because sizeof(req_) depends on the type of T, which means the class definition should be like this:

template <typename T>
class ReqWrap : public AsyncWrap {
 private:
  // req_wrap_queue_ comes before any templated member, which places it in a
  // fixed offset from the start of the class
  ListNode<ReqWrap> req_wrap_queue_;

  T req_;
};

instead of:

template <typename T>
class ReqWrap : public AsyncWrap {
 private:
  T req_;

  // req_wrap_queue_ comes after a templated member, which means it won't be in
  // a fixed offset from the start of the class
  ListNode<ReqWrap> req_wrap_queue_;
};

There are also tests on test/cctest/test_node_postmortem_metadata.cc to make sure all Node postmortem metadata are calculated correctly.

Tools and References