Skip to content

Instantly share code, notes, and snippets.

@tjfontaine
Last active June 6, 2023 17:42
Show Gist options
  • Save tjfontaine/9244374 to your computer and use it in GitHub Desktop.
Save tjfontaine/9244374 to your computer and use it in GitHub Desktop.

MDB is unlike most debuggers you've experienced.

It is not a source level debugger like gdb or lldb or even Node's builtin debugger

Generally used for postmortem analysis.

Postmortem is for Production and Development

We operate mostly on core files, though you can attach to running processes as well.

--abort-on-uncaught-exception

We originally implemented it for SmartOS, but we needed it for Linux as well.

These demos will be done in Manta, an Object Store with Compute built right in. But it works in any Illumos based install.

http://www.joyent.com/developers/node/debug/mdb

Node doesn't do anything useful by default

$ gcore $(pgrep -n node)

$ mdb core<tab>

> $C

> ^D

$ rm core<tab>

catch it in the act, see it's mostly hex stack frames from the JIT'd code

# dtrace -w -n 'node*::* { stop(); system("gcore -o core.%%t %d", pid); system("prun %d", pid); exit(0); }'

# mdb core<tab>

> $G

> $C

Let's see all the frames including the javascript ones, even if the JIT inlines them


> ::load v8

> ::jsstack

We can see arguments and files and offsets into those files


> ::jsstack -vn0

But as it turns out, we carry all the source code along with us anyway


> ::jsstack -v

Now what you want to be able to do is inspect objects


> <addr>::jsprint

But maybe the state we need to inspect isn't an argument. We just want to know how many objects there are out there.


> ::findjsobjects -va

Or sort by the count


> ::findjsobjects ! sort -k2

Or sort by the number of elements in an array or properties on an object


> ::findjsobjects ! sort -k3

We can find objects by constructor


> ::findjsobjects -c ClientRequest

Find objects by property


> ::findjsobjects -p _readableState


```

You can pipeline things together to inspect the state as well, this example will show currently loaded modules and which module was responsible for loading them

```

> ::findjsobjects -c Module | ::findjsobjects | ::jsprint id parent.id

```


`::findjsobjects` actually lists representative object address, so you need to pipe back through `::findjsobjects` to list them all

```
> <addr>::jsprint

> <addr>::findjsobjects | ::jsprint

> <addr>::findjsobjects | ::jsprint -d 1 -a

```

You can also identify who's holding the references to these objects


```
::findjsobjects -c ClientRequest | ::findjsobjects | ::findjsobjects -r
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment