I''ve been playing around with the dtrace java vm agents available at: https://solaris10-dtrace-vm-agents.dev.java.net/. They seem to work well examining an already-running-java instance but following a vm from birth to death is non-trivial. The dvm agent probes aren''t visible until the java vm starts and registers them so trying to start a dtrace script before the java instance doesn''t work. Neither does dtrace -c or the $target macro (and java restarts itself to pick the appropriate 32/64 bit binary). The approach I took was to write another script (see script below--thanks, dtrace! :)) that stops java processes if they register dvm probes. At that point, the dtrace script you really care about can be started and the java process restarted before you miss anything interesting. Not that I didn''t have fun writing the stop() script, but is there a better way? If not, the script below may be useful to others...constructive criticism welcome! ---CUT--- [i]#!/usr/sbin/dtrace -Cs #pragma D option destructive /* Watch for java processes which open the dtrace helper device. If libdvm[pt]i modules register DOF helpers, stop() the process after the probes are visible to dtrace but before the java VM has a chance to do anything "interesting". At this point, dvm probes of interest can be enabled (in another dtrace script) and the java process can be re-started with prun. */ #define string __C_string /* Hack for kstat.h problem--see Sun bugid 6207207 */ #include <dtrace.h> #undef string /* Hack for kstat.h problem--see Sun bugid 6207207 */ syscall::open*:entry /* catch open() and open64() */ / execname=="java" / { self->file=arg0; } syscall::open*:return /* catch open() and open64() */ / self->file && copyinstr(self->file) == "/devices/pseudo/dtrace at 0:helper" / { self->fd=arg1; self->file=0; } syscall::ioctl:entry / (arg0==self->fd) && (arg1==DTRACEHIOC_ADDDOF) / { self->dh=(struct dof_helper *)copyin(arg2,sizeof(struct dof_helper)); self->fd=0; } syscall::ioctl:return / (self->dh->dofhp_mod=="libdvmpi.so") || (self->dh->dofhp_mod=="libdvmti.so") / { stop(); } syscall::ioctl:return /* unset self->dh regardless what dofhp_mod is */ { self->dh=0; } [/i] ---CUT--- This message posted from opensolaris.org
Hey Frank, I encountered a situation where I had to write a similar script -- though I admit that mine was a bit more ad hoc. The full script can be found in this blog post: http://blogs.sun.com/roller/page/ahl/?anchor=java_debugging_w_dtrace We''re working on a better way of doing this -- we should probably include a script like yours with the JVM agents since it''s such a common practice. Adam On Mon, Aug 29, 2005 at 01:48:44PM -0700, Frank Stuart wrote:> I''ve been playing around with the dtrace java vm agents available at: https://solaris10-dtrace-vm-agents.dev.java.net/. They seem to work well examining an already-running-java instance but following a vm from birth to death is non-trivial. > > The dvm agent probes aren''t visible until the java vm starts and registers them so trying to start a dtrace script before the java instance doesn''t work. Neither does dtrace -c or the $target macro (and java restarts itself to pick the appropriate 32/64 bit binary). > > The approach I took was to write another script (see script below--thanks, dtrace! :)) that stops java processes if they register dvm probes. At that point, the dtrace script you really care about can be started and the java process restarted before you miss anything interesting. > > Not that I didn''t have fun writing the stop() script, but is there a better way? If not, the script below may be useful to others...constructive criticism welcome! > > ---CUT--- > [i]#!/usr/sbin/dtrace -Cs > > #pragma D option destructive > > /* > Watch for java processes which open the dtrace helper device. If > libdvm[pt]i modules register DOF helpers, stop() the process after > the probes are visible to dtrace but before the java VM has a chance > to do anything "interesting". At this point, dvm probes of interest > can be enabled (in another dtrace script) and the java process can > be re-started with prun. > */ > > #define string __C_string /* Hack for kstat.h problem--see Sun bugid 6207207 */ > #include <dtrace.h> > #undef string /* Hack for kstat.h problem--see Sun bugid 6207207 */ > > syscall::open*:entry /* catch open() and open64() */ > / execname=="java" / > { > self->file=arg0; > } > > syscall::open*:return /* catch open() and open64() */ > / self->file && copyinstr(self->file) == "/devices/pseudo/dtrace at 0:helper" / > { > self->fd=arg1; > self->file=0; > } > > syscall::ioctl:entry > / (arg0==self->fd) && (arg1==DTRACEHIOC_ADDDOF) / > { > self->dh=(struct dof_helper *)copyin(arg2,sizeof(struct dof_helper)); > self->fd=0; > } > > syscall::ioctl:return > / (self->dh->dofhp_mod=="libdvmpi.so") || (self->dh->dofhp_mod=="libdvmti.so") / > { > stop(); > } > > syscall::ioctl:return /* unset self->dh regardless what dofhp_mod is */ > { > self->dh=0; > } > [/i] > ---CUT--- > This message posted from opensolaris.org > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org-- Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl
> We''re working on a better way of doing this -- we > should probably include > a script like yours with the JVM agents since it''s > such a common practice.Thinking about this a bit more, maybe a better way is to have the library optionally stop its own jvm process after enabling the probes. Then you can do something like [b]java -Xrundvm[pt]i:all:stop myclass[/b] ...no extra script required and it allows you to concurrently stop some java processes but not others. Nevertheless, feel free to use the script if its useful. This message posted from opensolaris.org
On Mon, Sep 12, 2005 at 03:03:10PM -0700, Frank Stuart wrote:> Thinking about this a bit more, maybe a better way is to have the library optionally stop its own jvm process after enabling the probes. Then you can do something like [b]java -Xrundvm[pt]i:all:stop myclass[/b] ...no extra script required and it allows you to concurrently stop some java processes but not others. > > Nevertheless, feel free to use the script if its useful.Hey Frank, In the next version of Solaris and in an S10 patch, you won''t need the startup script -- dtrace will automatically pick up new probes when the new module is loaded. I just putback the code to the S10 patch gate -- I''ll post here once the patch is available. Adam -- Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl