On Tue, Sep 09, 2008 at 02:49:18AM +0200, Henrik Johansson wrote:
> Hello all,
> 
> I saw this question about a year back in the archive[1], but with no  
> final answer.
> 
> I would like to trace shmget calls and also get the id of the shared  
> memory segment.
> 
> That script looked like[2], but we dont get the id since arg1 is the  
> errno value.
> 
> How do i access the shm id, i would need this to debug a customer  
> problem but i don't have time to learn it the hard way.


If you look at the arguments of shmget:

# dtrace -lv -n fbt::shmget:
   ID   PROVIDER            MODULE                          FUNCTION NAME
79745        fbt            shmsys                            shmget entry

        Probe Description Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: Unknown

        Argument Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: ISA

        Argument Types
                args[0]: key_t
                args[1]: size_t
                args[2]: int
                args[3]: uintptr_t *


79746        fbt            shmsys                            shmget return

        Probe Description Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: Unknown

        Argument Attributes
                Identifier Names: Private
                Data Semantics:   Private
                Dependency Class: ISA

        Argument Types
                args[0]: int
                args[1]: int

and the code for shmsys: 

http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/os/shm.c#shmsys
static uintptr_t
shmsys(int opcode, uintptr_t a0, uintptr_t a1, uintptr_t a2)
{
        int     error;
        uintptr_t r_val = 0;

        switch (opcode) {
...
        case SHMGET:
                error = shmget((key_t)a0, (size_t)a1, (int)a2, &r_val);
                break;
...
        }

        if (error)
                return ((uintptr_t)set_errno(error));

        return (r_val);
}

You'll see that the return value is passed through a pointer in the fourth
argument.  The simplest way to change your script is to do:

--- cut here ---
#!/usr/sbin/dtrace -s

#pragma D option quiet

dtrace:::BEGIN
{
     /* operation  key  shmid  size  flags cpu wall */
     printf("%-10s %-10s %-10s %-10s %-10s %-10s %-10s\n", "operation",
                                                     "key", "shmid",
                                                     "size", "flags",
                                                     "CPU", "Wall Time");
}

fbt::shmget:entry
{
    self->key = args[0];
    self->size = args[1];
    self->flags = args[2];
    self->shmidp = args[3];

    self->shmgettimestamp = timestamp;
    self->shmgetvtimestamp = vtimestamp;
}

fbt::shmget:return
/ self->shmgettimestamp /
{
    /* operation  key  shmid  size  flags cpu wall */
    printf("%-10s %-10x %-10x %-10d %-10d %-10d %-10d\n", probefunc,
                                           self->key, *self->shmidp,
                                           self->size, self->flags,
                                           vtimestamp - self->shmgetvtimestamp,
                                           timestamp - self->shmgettimestamp);
}
--- cut here ---

Note that I've switched to using args[n] probes, instead of argn.  For FBT
probes, this makes sure the types work correctly.

Cheers,
- jonathan




_______________________________________________
dtrace-discuss mailing list
[email protected]

Reply via email to