tag:blogger.com,1999:blog-8721363458984590257.post6399928165837875243..comments2023-06-27T09:20:30.886+01:00Comments on Byteman Blog: Byteman 1.2.0 Bytes Deeper Into Your CodeAndrew Dinnhttp://www.blogger.com/profile/05800566216491514191noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-8721363458984590257.post-18974943615757560192017-11-15T06:44:27.735+00:002017-11-15T06:44:27.735+00:00This comment has been removed by a blog administrator.Bloggerhttps://www.blogger.com/profile/07287821785570247118noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-36154850697199102732010-02-10T07:42:28.414+00:002010-02-10T07:42:28.414+00:00Hi Andrew,
Thanks for your prompt reply. Much app...Hi Andrew,<br /><br />Thanks for your prompt reply. Much appreciated :)<br />Actually instrumentation happens, but no <br />output of classes.<br />I have posted the question again in the <br />byteman user forum at www.jboss.org/byteman, <br />as suggested by you.<br />Please have a look there.<br />Thanks for looking into it.<br /><br />cheers,<br />jayjayhttps://www.blogger.com/profile/14219532373735319413noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-71188956688882777972010-02-05T13:30:37.958+00:002010-02-05T13:30:37.958+00:00oops, sorry that URL should have read www.jboss.or...oops, sorry that URL should have read www.jboss.org/byteman -- click on the community tab for the user forumAndrew Dinnhttps://www.blogger.com/profile/05800566216491514191noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-9669063785977562662010-02-05T13:27:13.755+00:002010-02-05T13:27:13.755+00:00Hi Jay,
Hmm, I am not sure about what is happenin...Hi Jay,<br /><br />Hmm, I am not sure about what is happening here but the lack of any transformation is perhaps more telling than the lack of dumped files -- if no classes get modified then there is no code to dump. Try switching on trace with -Dorg.jboss.byteman.verbose to see if it is attempting to transform anything. If that fails perhaps you could report this on the Byteman user forum (accessible via ww.org.jboss.byteman) and I will look into it in more detail.Andrew Dinnhttps://www.blogger.com/profile/05800566216491514191noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-56499248708651842852010-02-05T10:48:28.829+00:002010-02-05T10:48:28.829+00:00Hi Andrew,
Tried to output the transformed class ...Hi Andrew,<br /><br />Tried to output the transformed class using the<br />system property -Dorg.jboss.byteman.dump.generated.classes=1 -Dorg.jboss.byteman.dump.generated.classes.directory=c:\\temp\\junk, but byteman did not write out<br />anything. In fact, the transformation did not happen at all and the program ran without instrumentation.<br />Have I defined the properties ok ? I also tried the value "true" for the system property org.jboss.byteman.dump.generated.classes, but no luck.<br /><br />cheers,<br />jayjayhttps://www.blogger.com/profile/14219532373735319413noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-36954155718798732662010-01-13T08:52:57.501+00:002010-01-13T08:52:57.501+00:00Hi Andrew,
Ah, . Ok. Thanks for the information.
...Hi Andrew,<br /><br />Ah, . Ok. Thanks for the information.<br />cheers,<br />jayjayhttps://www.blogger.com/profile/14219532373735319413noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-7095635682970927912010-01-12T11:15:22.151+00:002010-01-12T11:15:22.151+00:00Ah, my apologies for the missing method name. I ac...Ah, my apologies for the missing method name. I actually entered the name for the class initialiser which is <clinit>. I forgot to write it using &lt; and &gt; so it got elided as an unknown HTML tag.<br /><br />The <clinit> method is preferable to the <init> method because the rule only fires once at class load time. However, there is a drawback with injecting code into this method.<br /><br />If you try to submit the rules via the agent listener after the program has started then the clinit rule may not get triggered. If the class has already been loaded when the rules are submitted then the methods will be redefined and recompiled. However, the class static init code is not rerun so the rule code will not get executed. So, <clinit> rules are only recommended for loading via the JVM/agent command line.<br /><br />regards,<br /><br /><br />Andrew Dinn<br />-----------Andrew Dinnhttps://www.blogger.com/profile/05800566216491514191noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-46983042760044108212010-01-12T09:19:30.561+00:002010-01-12T09:19:30.561+00:00Hi Andrew,
Thanks once again for your detailed ex...Hi Andrew,<br /><br />Thanks once again for your detailed explanation.<br />In short, yes, I was afraid you were going to say that :)<br />But yes, the race condition is easy to simulate and test. I will use that since I cannot simulate the "old value boolean test"<br />using byteman library.<br />By the way, your script has some errors. I noticed that when I ran it.<br />Here are the errors I noticed :<br />1) in rules 1 and 3 the method name is missing<br />2) rendezvous call has a 2nd parm., which should not be there.<br /><br />I made some corrections and came up with the following script :<br /><br />RULE setup rendezvous<br />CLASS AppServerEnv<br />METHOD "<"init">"()<br />IF TRUE<br />DO traceln( "creating _instance in thread " + Thread.currentThread() ), <br /> createRendezvous("AppServerEnv", 2)<br />ENDRULE<br />#<br />RULE enforce rendezvous before write<br />CLASS AppServerEnv<br />METHOD getInstance()<br />AT WRITE _instance<br />IF TRUE<br />DO traceln( "writing _instance in thread " + Thread.currentThread() ),<br /> rendezvous("AppServerEnv")<br />ENDRULE<br /><br />Please note that I had to put " sign in the method name, otherwise my posted comment, in this blog, removes the left/right parantheses and<br />everything between.<br />Of course, in this case, createRendezvous() <br />will be executed for each thread, but only<br />the first execution of it will succeed and<br />subsequent ones will fail anyway.<br />So it does not matter, right ?<br />Is this ok ?<br /><br />cheers,<br />jayjayhttps://www.blogger.com/profile/14219532373735319413noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-14675061080426922142010-01-11T13:36:13.553+00:002010-01-11T13:36:13.553+00:00Hi Jay,
There is indeed a danger with your unsync...Hi Jay,<br /><br />There is indeed a danger with your unsynchronized static that thread 2 may see an uninitialised version of the AppServerEnv object. That is to do with the way the memory system works on multi-core or multi-processor systems. From the point of view of Thread 1 the constructor will always be executed before assigning the static field _instance. However, in the absence of a synchronization it is possible on certain hardware architectures that Thread 2 may see the assignment to _instance but not see the assignment to field _isProduction of that instance. In other words the writes may happen out of order when viewed form a parallel thread. A memory barrier instruction of the appropriate type must be executed by both the writer thread and the reader thread in order to ensure that writes are published before they are read. A Java compiler will only generate these instructions when the source code doing the write and/or read is synchronized.<br /><br />Now, there is no way you can manifest this behaviour using Byteman because Byteman can only introduce orderings between threads by introducing synchronization operations. This will ensure that any out of order operations which might be visible to other threads are completed by the writer thread before they can be seen in the reader thread. So, when you reorder things using byteman memory operations will strictly follow source code order before and after the point at which you inject the rule code.<br /><br />That said, you can write some Byteman rules to manifest the race condition implicit in this class. Here is what you need:<br /><br />RULE setup rendezvous<br />CLASS AppServerEnv<br />METHOD <br />IF TRUE<br />DO createRendezvous("AppServerEnv", 2)<br />ENDRULE<br /><br />RULE enforce rendezvous before write<br />CLASS AppServerEnv<br />METHOD getInstance()<br />AT WRITE _instance<br />IF TRUE<br />DO traceln("writing _instance in thread " + Thread.currentThread()) rendezvous("AppServerEnv", 2)<br /><br />RULE trace create calls<br />CLASS AppServerEnv<br />METHOD <br />AT ENTRY<br />IF TRUE<br />DO traceln("creating _instance in thread " + Thread.currentThread()) <br />ENDRULE<br /><br />The first rule gets run when the AppServerEnv is loaded and sets up a 2 way rendezvous. The second rule is triggered just before field _instance is written. So, the first thread to enter getInstance() will wat before completing its write, allowing the second thread to also create and write the field. Once both threads are ready to assign the instance they will pass the rendezvous and each one will perform the assignment in turn.Andrew Dinnhttps://www.blogger.com/profile/05800566216491514191noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-81558852460399158482010-01-11T12:57:12.438+00:002010-01-11T12:57:12.438+00:00Hi Andrew,
I have a problem for which I would lik...Hi Andrew,<br /><br />I have a problem for which I would like your advice.<br />Here is a harmless looking class that has a major and "difficult-to-test" problem : <br />public class AppServerEnv {<br /><br /> private boolean _isProduction;<br /> // solution-1<br /> //private final boolean _isProduction;<br /> <br /> private static AppServerEnv _instance;<br /><br /> private AppServerEnv( ) {<br /> _isProduction = Boolean.getBoolean( "production" );<br /> }<br /> <br /> public static AppServerEnv getInstance( ) {<br /> // solution-1<br /> //public synchronized static AppServerEnv getInstance( ) {<br /> if( _instance == null )<br /> _instance = new AppServerEnv( );<br /> return _instance;<br /> }<br /> <br /> public boolean isProduction( ) {<br /> return _isProduction;<br /> }<br /> <br />}<br /><br />Let's have 2 threads thread-1 and thread-2.<br />Thread-1 is in getInstance(), finds _instance==null and starts to execute the following line :<br /><br />_instance = new AppServerEnv( );<br /><br />Now, _instance could get updated "before" the constructor.<br />Thread-2 comes along, checks _instance != null, picks<br />up the _instance and calls isProduction() to get an old value of the boolean _isProduction, since Thread-1 has not yet completed the constructor execution.<br />The problem here is to do with the actual<br />execution sequence of the "new..." call on the<br />target CPU. Since byteman uses the bytecode to <br />simulate the interleaving of threads, I am<br />guessing that it is "impossible" to simulate<br />this interleaving using the byteman library.<br />Or am I wrong ?<br />Any suggestions, tips, assistance will be much<br />appreciated.<br /><br />cheers,<br />jayjayhttps://www.blogger.com/profile/14219532373735319413noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-84531076482649890202010-01-04T09:18:06.654+00:002010-01-04T09:18:06.654+00:00Thanks for the tip and the ever-positive feedback....Thanks for the tip and the ever-positive feedback.<br /><br />regards,<br /><br /><br />Andrew Dinn<br />-----------Andrew Dinnhttps://www.blogger.com/profile/05800566216491514191noreply@blogger.comtag:blogger.com,1999:blog-8721363458984590257.post-87596197918022393322009-12-31T08:13:45.268+00:002009-12-31T08:13:45.268+00:00Hi Andrew,
Nice to see a blog just for byteman rel...Hi Andrew,<br />Nice to see a blog just for byteman related <br />discussions.<br />The ^ functionality is powerful, awesome.<br />By the way, your README for release 1.2.0.1 says 1.1.1 :)<br />cheers,<br />jayjayhttps://www.blogger.com/profile/14219532373735319413noreply@blogger.com