1# Postmortem support 2 3Postmortem metadata are constants present in the final build which can be used 4by debuggers and other tools to navigate through internal structures of software 5when analyzing its memory (either on a running process or a core dump). Node.js 6provides this metadata in its builds for V8 and Node.js internal structures. 7 8## V8 postmortem metadata 9 10V8 prefixes all postmortem constants with `v8dbg_`, and they allow inspection of 11objects on the heap as well as object properties and references. V8 generates 12those symbols with a script (`deps/v8/tools/gen-postmortem-metadata.py`), and 13Node.js always includes these constants in the final build. 14 15## Node.js debug symbols 16 17Node.js prefixes all postmortem constants with `nodedbg_`, and they complement 18V8 constants by providing ways to inspect Node.js-specific structures, like 19`node::Environment`, `node::BaseObject` and its descendants, classes from 20`src/utils.h` and others. Those constants are declared in 21`src/node_postmortem_metadata.cc`, and most of them are calculated at compile 22time. 23 24### Calculating offset of class members 25 26Node.js constants referring to the offset of class members in memory 27are calculated at compile time. 28Because of that, those class members must be at a fixed offset 29from the start of the class. That's not a problem in most cases, but it also 30means that those members should always come after any templated member on the 31class definition. 32 33For example, if we want to add a constant with the offset for 34`ReqWrap::req_wrap_queue_`, it should be defined after `ReqWrap::req_`, because 35`sizeof(req_)` depends on the type of T, which means the class definition should 36be like this: 37 38```cpp 39template <typename T> 40class ReqWrap : public AsyncWrap { 41 private: 42 // req_wrap_queue_ comes before any templated member, which places it in a 43 // fixed offset from the start of the class 44 ListNode<ReqWrap> req_wrap_queue_; 45 46 T req_; 47}; 48``` 49 50instead of: 51 52```cpp 53template <typename T> 54class ReqWrap : public AsyncWrap { 55 private: 56 T req_; 57 58 // req_wrap_queue_ comes after a templated member, which means it won't be in 59 // a fixed offset from the start of the class 60 ListNode<ReqWrap> req_wrap_queue_; 61}; 62``` 63 64There are also tests on `test/cctest/test_node_postmortem_metadata.cc` to make 65sure all Node.js postmortem metadata are calculated correctly. 66 67## Tools and references 68 69* [llnode](https://github.com/nodejs/llnode): LLDB plugin 70* [`mdb_v8`](https://github.com/joyent/mdb_v8): mdb plugin 71* [nodejs/post-mortem](https://github.com/nodejs/post-mortem): Node.js 72post-mortem working group 73