2021-02-24 08:57:45 +05:30
|
|
|
# Postmortem support
|
2017-12-25 22:17:25 -02:00
|
|
|
|
|
|
|
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
|
2018-03-04 22:46:49 +09:00
|
|
|
when analyzing its memory (either on a running process or a core dump). Node.js
|
|
|
|
provides this metadata in its builds for V8 and Node.js internal structures.
|
2017-12-25 22:17:25 -02:00
|
|
|
|
2021-02-24 08:57:45 +05:30
|
|
|
## V8 postmortem metadata
|
2017-12-25 22:17:25 -02:00
|
|
|
|
|
|
|
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
|
2018-03-04 22:46:49 +09:00
|
|
|
Node.js always includes these constants in the final build.
|
2017-12-25 22:17:25 -02:00
|
|
|
|
2021-02-24 08:57:45 +05:30
|
|
|
## Node.js debug symbols
|
2017-12-25 22:17:25 -02:00
|
|
|
|
2018-10-29 22:04:25 -07:00
|
|
|
Node.js prefixes all postmortem constants with `nodedbg_`, and they complement
|
|
|
|
V8 constants by providing ways to inspect Node.js-specific structures, like
|
2017-12-25 22:17:25 -02:00
|
|
|
`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.
|
|
|
|
|
2019-08-27 00:07:14 -04:00
|
|
|
### Calculating offset of class members
|
2017-12-25 22:17:25 -02:00
|
|
|
|
2018-03-04 22:46:49 +09:00
|
|
|
Node.js 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
|
2017-12-25 22:17:25 -02:00
|
|
|
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:
|
|
|
|
|
2020-05-20 09:35:59 -04:00
|
|
|
```cpp
|
2017-12-25 22:17:25 -02:00
|
|
|
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:
|
|
|
|
|
2020-05-20 09:35:59 -04:00
|
|
|
```cpp
|
2017-12-25 22:17:25 -02:00
|
|
|
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
|
2018-10-29 22:04:25 -07:00
|
|
|
sure all Node.js postmortem metadata are calculated correctly.
|
2017-12-25 22:17:25 -02:00
|
|
|
|
2021-02-24 08:57:45 +05:30
|
|
|
## Tools and references
|
2017-12-25 22:17:25 -02:00
|
|
|
|
|
|
|
* [llnode](https://github.com/nodejs/llnode): LLDB plugin
|
2021-10-30 15:40:34 -07:00
|
|
|
* [`mdb_v8`](https://github.com/joyent/mdb_v8): mdb plugin
|
2017-12-25 22:17:25 -02:00
|
|
|
* [nodejs/post-mortem](https://github.com/nodejs/post-mortem): Node.js
|
2021-10-06 21:40:23 -07:00
|
|
|
post-mortem working group
|