Finally worked out how to use ::grep

The mdb(1) man page has this terse entry for ::grep:

::grep command
Evaluate the specified command string,  and  then  print
the  old  value  of  dot if the new value of dot is non-
zero. If the command contains whitespace or  metacharac-
ters,  it must be quoted. The ::grep dcmd can be used in
pipelines to filter a list of addresses.

I’ve struggled to work out how to use it till now. Take a look at this:

> ::walk umem_log | ::grep '*(.+4) == 37ac048' | ::bufctl_audit

The libumem umem_log walker extracts all the entries from the transaction log but I only want to see those that refer to a particular buffer (0x37ac048).

To do this we pipe the walker to ::grep which runs a command and then evaluates the value of ‘.’, the command in this case is just an expression. From the mdb(1) man page:

expression [! word ...] [ ; ]
A command can consist only of an arithmetic  expression.
The  expression is evaluated and the dot variable is set
to its value, and then the previous dcmd  and  arguments
are executed using the new value of dot.

The expression tests the value of the contents of ‘.+4’. Why? well…

typedef struct umem_bufctl_audit {
struct umem_bufctl      *bc_next;       /* next bufctl struct */
void                    *bc_addr;       /* address of buffer */
struct umem_slab        *bc_slab;       /* controlling slab */
umem_cache_t            *bc_cache;      /* controlling cache */
hrtime_t                bc_timestamp;   /* transaction time */
thread_t                bc_thread;      /* thread doing transaction */
struct umem_bufctl      *bc_lastlog;    /* last log entry */
void                    *bc_contents;   /* contents at last free */
int                     bc_depth;       /* stack depth */
uintptr_t               bc_stack[1];    /* pc stack */
} umem_bufctl_audit_t;
"/usr/include/umem_impl.h" [Read only] line 138 of 381 --36%--

If the contents match the expression evaluates to ‘1’ which means ::grep prints the old value of ‘.’. Hurrah.

Jan 24th 2007 – I now know what was confusing me here:

There’s still an outstanding question about why “the previous dcmd and arguments are executed using the new value of dot” doesn’t appear to apply in the ::grep line. eg:

> 1234=Y
1970 Jan  1 02:17:40
> ::grep .
1234
> ::grep '.=Y'
1970 Jan  1 02:17:40
1234
> .
1970 Jan  1 02:17:40
1234
> =Y
1970 Jan  1 02:17:40

I’m not going to worry about it.

The man page excerpt I quoted refers to using an expression on its own with no pipeline. In other words, if you just have an expression on the line it repeats the last dcmd with the new value of dot. Within a ::grep dcmd this doesn’t apply.

Advertisements
Previous Post
Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: