Paul van den Bogaard
2007-Jul-04 13:47 UTC
[dtrace-discuss] I do not understand. Please advise.
I have the following script: proc:::exec-success /execname == "java"/ { stop(); printf("Restart with prun %d\n", pid); } This one stops any java process that I start (and others :-). Runs as expected. I "prun pid" and that stopped java process continues. Now I add a single line directly after the printf: system("./scanit.d -p %d", pid); scanit.d uses the hotspot probes to dive into this java process just started. If scanit.d is started from the command line it works as I expect it. However when started through the above mentioned "system(...)" way, an error is raised and the stopped java process is started again! The message is: dtrace: failed to compile script ./scanit.d: line 17: args[ ] may not be referenced because probe description hotspot4051:::method-entry matches an unstable set of probes What am I missing? (and yes I did start the java process with -XX:+ExtendedDTraceProbes) Thanks Paul -- This message posted from opensolaris.org
Hi Paul, It sounds like the ''scanit.d'' script is using the args[] array, but should instead be using argN variables, but it''s hard to say without seeing the script. Are you able to run ''scanit.d'' by hand? Adam On Wed, Jul 04, 2007 at 06:47:28AM -0700, Paul van den Bogaard wrote:> I have the following script: > > proc:::exec-success > /execname == "java"/ > { > stop(); > printf("Restart with prun %d\n", pid); > } > > This one stops any java process that I start (and others :-). Runs as expected. I "prun pid" and that stopped java process continues. > > Now I add a single line directly after the printf: > > system("./scanit.d -p %d", pid); > > scanit.d uses the hotspot probes to dive into this java process just started. If scanit.d is started from the command line it works as I expect it. However when started through the above mentioned "system(...)" way, an error is raised and the stopped java process is started again! > > The message is: > > dtrace: failed to compile script ./scanit.d: line 17: args[ ] may not be referenced because probe description hotspot4051:::method-entry matches an unstable set of probes > > What am I missing? (and yes I did start the java process with -XX:+ExtendedDTraceProbes) > > Thanks > Paul > -- > 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
system(3) takes 1 argument only: int system(const char *command); In your case, you will need to use sprintf(3) to generate the needed string. Rayson On 7/4/07, Paul van den Bogaard <Paul.VandenBogaard at sun.com> wrote:> I have the following script: > > proc:::exec-success > /execname == "java"/ > { > stop(); > printf("Restart with prun %d\n", pid); > } > > This one stops any java process that I start (and others :-). Runs as expected. I "prun pid" and that stopped java process continues. > > Now I add a single line directly after the printf: > > system("./scanit.d -p %d", pid); > > scanit.d uses the hotspot probes to dive into this java process just started. If scanit.d is started from the command line it works as I expect it. However when started through the above mentioned "system(...)" way, an error is raised and the stopped java process is started again! > > The message is: > > dtrace: failed to compile script ./scanit.d: line 17: args[ ] may not be referenced because probe description hotspot4051:::method-entry matches an unstable set of probes > > What am I missing? (and yes I did start the java process with -XX:+ExtendedDTraceProbes) > > Thanks > Paul > -- > This message posted from opensolaris.org > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org >
Sorry, ignore my previous message, I was thinking in C/C++ :( Rayson On 7/4/07, Rayson Ho <rayrayson at gmail.com> wrote:> system(3) takes 1 argument only: > > int system(const char *command); > > In your case, you will need to use sprintf(3) to generate the needed string. > > Rayson > > > > On 7/4/07, Paul van den Bogaard <Paul.VandenBogaard at sun.com> wrote: > > I have the following script: > > > > proc:::exec-success > > /execname == "java"/ > > { > > stop(); > > printf("Restart with prun %d\n", pid); > > } > > > > This one stops any java process that I start (and others :-). Runs as expected. I "prun pid" and that stopped java process continues. > > > > Now I add a single line directly after the printf: > > > > system("./scanit.d -p %d", pid); > > > > scanit.d uses the hotspot probes to dive into this java process just started. If scanit.d is started from the command line it works as I expect it. However when started through the above mentioned "system(...)" way, an error is raised and the stopped java process is started again! > > > > The message is: > > > > dtrace: failed to compile script ./scanit.d: line 17: args[ ] may not be referenced because probe description hotspot4051:::method-entry matches an unstable set of probes > > > > What am I missing? (and yes I did start the java process with -XX:+ExtendedDTraceProbes) > > > > Thanks > > Paul > > -- > > This message posted from opensolaris.org > > _______________________________________________ > > dtrace-discuss mailing list > > dtrace-discuss at opensolaris.org > > >
Paul van den Bogaard
2007-Jul-05 17:02 UTC
[dtrace-discuss] I do not understand. Please advise.
*What did some further testing on this subject. Please find here my findings and ideas. Still open ended. I am now stuck in my way of thinking. Like going around in circles. I like to instrument a process of which I know it will be created but I do not have the pid yet. Looking for a creative idea that could help me get out of this chicken and egg situation? These tests are all performed on a single code AMD U20 workstation running Solaris 10, Update 3. *Why I am trying to optimize a JDBC (pure Java) driver used for SPECjApps benchmarks. The SPEC setup is quite complex. Therefore it would be very convenient if I could make this stop in "proc:::exec" work in order to determine the pid of the java process started and then start a next script that needs this pid. This would enable me to focus on tracing specific classes (likely jdbc related). I have read about other methods to get a VM started with a pause option. Indeed this works, however the stop() and go method I am trying to get working is simpler in use. *The DTrace scripts: #!/usr/sbin/dtrace -Zs #pragma D option quiet #pragma D option destructive int watchpid; proc:::exec-success /pid == watchpid/ { stop(); printf("process \"%s\" %d stopped. Use prun %d to activate\n", stringof(curpsinfo->pr_fname), pid,pid); system("./misf.d %d", pid); } proc:::exec-success /execname == "java" && watchpid == 0/ { watchpid = pid; } *Some remarks A java process re-execs itself so I like to get a hold of the second exec. I think the above script takes care of that ''problem''. Now I have a handle on the process. I stop the correct one. Then it launches the script misf.d with as a single parameter the pid of that java process. *Interesting Observations: 1) if misf.d is started with the -p pid option (and misf.d has probes specified as "hotspot$target:::method-entry" than this automagically starts the stopped process: no prun is needed. 2) when using it as in the code snippet above and handled like "hotspot$1:::method-entry" I need to use prun to wake up the Java process. My adhoc impression: an undocumented feature. *The misf.d script: #!/usr/sbin/dtrace -Zs #pragma D option quiet self string class; hotspot$1:::method-entry { this->str_ptr = (char*) copyin(arg1, arg2+1); this->str_ptr[arg2] = ''\0''; self->class = (string) this->str_ptr; printf("%s\n", self->class); } Of course the original version is a little bit more complex, however this one shows what is happening. *What happens If I remove the -Z option from the first line in misf.d (#!/usr/sbin/dtrace -Zs) I get a DTrace error message telling me it found no matching probes. I think this is due to the fact that all these hotspot probes are part of libjvm.so. A library that is not (completely?) loaded at this point in time. When the misf.d script starts the java process is already stopped, therefore this DTrace script does not find any probes. And indeed leaving the -Z option in place results in absolutely no output at all. Probes that do not exist can not be activated, so will never fire. *Extra info on the hotspot provider According to the docs there is a hotspot<pid>:::init-vm-end. I was hoping I could create a clause on the probe spec like "hotspot*:::init-vm-end" and use stop() in this clause. However the probe I am interested in is that of the JVM that still needs to be started and not of any other already started VM. Therefore my probe does not exist and therefore can not be activated: I cannot catch my init-vm-end, since a non-activated probe will never fire... *Request for enhancement Both for the hotspot and the pid provider: let the probe specification in DTrace scripts be like a template. Once a probe that matches the template is created (after the DTrace script is started) it will be placed into instrumented mode. In my example this means I create an interst for the probe "hotspot*:::vm-init-end". Start my DTrace script. And some time later I start a JVM. Since I expressed my interest automatically a probe for this newly created process is activated so it will fire if this VM --in this example-- finishes its initialisation. *More tests I also did a two stage stop. ./t.d to create the first stop. This time t.d did not do the system() after that stop(). Then from a different window a dtrace -wqn ''pidDDDDD::main:entry { stop(); }'' (replace DDDD with the pid of the java proces I just learned) Indeed this works but while this second stop is holding the app frozen a dtrace -qn ''hotspotDDDD:::method-entry { printf("Method called\n"); }'' does indeed reproduce that error: no matching probes. the above mentioned double stops need ofcourse a prun DDDD each to get any progress ;^) So even if I have a handle on the main() {} of the VM I still have no access to the hotspot probes. *The Java program public class T { public int a() { return (int)(Math.random() * 1000.0);} public int b() { return a(); } public int c() { return b() + a(); } public int d(int a) { return a + c(); } static public void main(String[] args) throws Exception { Thread.sleep(1000* Integer.parseInt(args[0])); System.out.println((new T()).d(1) ); } } is started like java -XX:+ExtendedDTraceProbes T 1 (you have to use Java SE 6 for this) *Some remarks when I replace the parameter with say 30 it sleeps 30 seconds before doing the method calling. This gives me enough time to determine its pid and do a misf.d from another shell. In this case the misf.d script behaves as I expect. This is the reason why I think it could be related to library loading. -- This message posted from opensolaris.org