Here's the way I get Erlang Process ID's for Erlang-DTrace probes
right now:
Process* parent; // ...
Process *p; // ...
ERLANG_DTRACE_SPAWN(parent->id, /*...*/ p->id);
I simply pass the raw Erlang Process ID to DTrace.
It is very simple.
This work for PIDs within the same Erlang VM, which, because of the
probes I have, is all I can expose right now.
But, it doesn't work when comparing internal Erlang process ID's with
the same process id surfaced by a different Erlang VM (Node).
So, I need to build a little structure to represent the Erlang Process
ID, so that it can be compared for equality correctly, even if one
DTrace probe surfaces the PID from its own Erlang VM, and another
DTrace probe surfaces the PID from a 'foreign' Erlang VM.
The structure needs the PID, and the NODE.
I'm aiming to wrap this up early next week.
Garry
Details:
The id field of Process is of type Eterm.
An Eterm is an unsigned int, or unsigned long, depending on the
architecture.
An Eterm is an Erlang (tagged) data type, described in erl_term.h.
An internal pid is (look at this with a fixed width font):
/*
* PID layout (internal pids):
*
* |3 3 2 2 2 2 2 2|2 2 2 2 1 1 1 1|1 1 1 1 1 1 | |
* |1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0|
* | | | | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |n n n n n n n n n n n n n n n n n n n n n n n n n n n n|0 0|1 1|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* n : number
An external pid, is slightly different (again use a fixed width font),
also from erl_term.h:
/*
*
* External thing layout (external pids, ports, and refs):
*
* |3 3 2 2 2 2 2 2|2 2 2 2 1 1 1 1|1 1 1 1 1 1 | |
* |1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0|
* | | | | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |A A A A A A A A A A A A A A A A A A A A A A A A A A|t t t t|0 0|
Thing
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N|
Next
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E|
ErlNode
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X|
Data 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* . . .
* . . .
* . . .
*
* A : Arity
* t : External pid thing tag (1100)
* t : External port thing tag (1101)
* t : External ref thing tag (1110)
* N : Next (external thing) pointer
* E : ErlNode pointer
* X : Type specific data
*
* External pid and port layout:
* External pids and ports only have one data word (Data 0) which
has
* the same layout as internal pids resp. internal ports.
*
I believe this means that the contents of Data 0 is still layed out
like an internal PID.
So there are two cases:
1. When the pid is referring to a process inside this Erlang VM, then
there is no ErlNode in the pid value, it is just a simple "immediate"
Eterm, and the ErlNode for the current VM needs to be found from
elsewhere.
2. When the PID is referring to a process in a different Erlang Node,
the PID value is actually an External PID, and the erlang node value
needs to be fished-out of where-ever and included.