Paul Riethmuller
2005-Jul-19 02:53 UTC
[dtrace-discuss] variable size limit & documentation
Bryan, I''m trying to use a Dtrace script with a modest size global variable and hit a problem. Looking for a solution, I turn to the docs and notice that option "dynvarsize" appears just once in the docs, and it refers you to Chapter 3, where there is no mention. It doesn''t help me anyhow. I have: #!/usr/sbin/dtrace -qws #pragma D option dynvarsize=2000000 uint64_t last[600][4]; .. but get an error: # ./thomson5 dtrace: failed to enable ''./thomson5'': DIF program content is invalid If I reduce the first dimension from 600 to 180, it works as expected. Actually I just noted 512 works but 513 breaks. So 16KB is the size limit for a variable ? Out of interest, could I declare my array [600][4] as a global in a loadable kernel module and store my data there ? Regards, Paul
> I''m trying to use a Dtrace script with a modest size > global variable and hit a problem. > > Looking for a solution, I turn to the docs and notice > that option "dynvarsize" appears just once in the docs, > and it refers you to Chapter 3, where there is no mention. > > It doesn''t help me anyhow.You''re right -- it doesn''t. This isn''t a dynamic variable, it''s a global variable. And yes, we have a static limit at 16K. This is limited by the dtrace(7D) variable dtrace_global_maxsize, which you may manually tune to a higher value.> I have: > > #!/usr/sbin/dtrace -qws > > #pragma D option dynvarsize=2000000 > > uint64_t last[600][4]; > > .. but get an error: > > > # ./thomson5 > dtrace: failed to enable ''./thomson5'': DIF program content is invalidApologies for the cryptic failure mode -- DTrace is confusing you for a denial-of-service attack. The easiest way to solve this would be to make this a dynamic variable instead of a statically-allocated variable. That is, make it an associative array: declare it as "last[int, int]."> Out of interest, could I declare my array [600][4] as > a global in a loadable kernel module and store my data > there ?No. DTrace can''t store to arbitrary kernel data; it would violate the safety constraint. Use an associative array instead... - Bryan -------------------------------------------------------------------------- Bryan Cantrill, Solaris Kernel Development. http://blogs.sun.com/bmc
On Tue, Jul 19, 2005 at 12:53:50PM +1000, Paul Riethmuller wrote:> > Bryan, > > I''m trying to use a Dtrace script with a modest size > global variable and hit a problem. > > Looking for a solution, I turn to the docs and notice > that option "dynvarsize" appears just once in the docs, > and it refers you to Chapter 3, where there is no mention. > > It doesn''t help me anyhow.dynvarsize doesn''t effect the size of non-associative global variables; it effects the "dynamic variable" pool, which used for: global associative arrays all thread-local variables and associative arrays> I have: > > #!/usr/sbin/dtrace -qws > > #pragma D option dynvarsize=2000000 > > uint64_t last[600][4]; > > .. but get an error: > > > # ./thomson5 > dtrace: failed to enable ''./thomson5'': DIF program content is invalidTo get a better error message, you can do: # echo ''dtrace_err_verbose/W1'' | mdb -kw dtrace_err_verbose: 0 = 0x1 # Running a similar script: # dtrace -s /dev/stdin <<EOF uint64_t last[600][4]; BEGIN{last[0][0] = 1} EOF dtrace DIF object error: [0]: oversized by-ref global dtrace: failed to enable ''/dev/stdin'': DIF program content is invalid # So the problem is that your global variable is too large. By default, global variables are limited to 16kb a piece, a size which is controlled by the global variable "dtrace_global_maxsize": http://cvs.opensolaris.org/source/xref/usr/src/uts/common/dtrace/dtrace.c#119 119 size_t dtrace_global_maxsize = (16 * 1024);> If I reduce the first dimension from 600 to 180, it works as > expected. Actually I just noted 512 works but 513 breaks. > > So 16KB is the size limit for a variable ? > > Out of interest, could I declare my array [600][4] as > a global in a loadable kernel module and store my data > there ?What are you using this variable for? Is there a reason you can''t just use an associative array or an aggregation for this? i.e., if you define the variable as: uint64_t last[int, int]; you can have an arbitrary number of array elements. Cheers, - jonathan P.S. As a work around, you could always increase dtrace_global_maxsize. On a 64-bit system: echo ''dtrace_global_maxsize/Z 1000000'' | mdb -k will let you have variables up to 16 megabytes in size, until you reboot the system. (this is, of course, an implementation detail subject to change with any patch) -- Jonathan Adams, Solaris Kernel Development