OpenSolaris

Printable Version Enter a New Search
Bug ID 6357600
Synopsis zero value in AGGKEY bufhandler does not match buffered output
State 10-Fix Delivered (Fix available in build)
Category:Subcategory library:libdtrace
Keywords
Responsible Engineer Bryan Cantrill
Reported Against
Duplicate Of
Introduced In
Commit to Fix snv_30
Fixed In snv_30
Release Fixed solaris_nevada(snv_30) , solaris_10u4(s10u4_03) (Bug ID:2139216)
Related Bugs
Submit Date 1-December-2005
Last Update Date 21-February-2007
Description
The buffered output handler makes a callback with invalid data (zero) under the following condiitions:
- multiple aggregations are passed to printa()
- format string places values ahead of the tuple

BEGIN
{
        @a[1] = sum(1);
        @b[1] = sum(2);
        @a[2] = sum(3);
        printa("[%d] %@d %@d\n", @a, @b);
        exit(0);
}

The above generates the expected callbacks from the buffered output handler:

  0      1                           :BEGIN [1] 1 2
[2] 3 0

However, if I change the printa format string so the tuple comes last:

        printa("%@d %@d [%d]\n", @a, @b);

then every callback with the AGGKEY flag set has a record value of zero, although the buffered output remains correct.  Also, the current record does not exist in the current aggdata.  That is, (dtbda_recdesc != &dtbda_aggdata->dtada_desc->dtagd_rec[i]) at any index i in the range (1 .. dtbda_aggdata->dtada_desc->dtagd_nrecs - 1).

Unfortunately, this behavior can't be demonstrated with the new dtrace(1M) -B option:

dtrace:   dtrace_bufdata:
dtrace:       dtbda_buffered => "1"
dtrace:          dtbda_probe => <NULL>
dtrace:        dtbda_aggdata => <non-NULL>
dtrace:        dtbda_recdesc => <non-NULL>
dtrace:          dtbda_flags => 0x1 (AGGKEY)
...
dtrace:   dtrace_recdesc:
dtrace:          dtrd_action => 1
dtrace:            dtrd_size => 4
dtrace:          dtrd_offset => 16
...

What would help here is the dereferenced value of (dtbda_aggdata->dtada_data + dtbda_recdesc->dtrd_offset) under the "dtrace_recdesc" header so it is possible to verify that the record value matches dtbda_buffered (in this case, 0 does not match "1").  Also, after

dtrace:   dtrace_aggdesc:
dtrace:           dtagd_name => "b"
dtrace:          dtagd_varid => 2
dtrace:             dtagd_id => 2
dtrace:          dtagd_nrecs => 3

it would help to display the index of the current record (in this case 3, the value of dtagd_nrecs), obtained

for (r = 1; r < aggdesc->dtagd_nrecs; ++r) {
        if (&aggdesc->dtagd_rec[r] == rec) {
                break;
        }
}
Work Around
N/A
Comments
N/A