I have found in docs for jstack:
jstack prints Java stack traces of Java threads for a given Java process or core
file or a remote debug server. For each Java frame, the full class name, method name,
'bci' (byte code index) and line number, if available, are printed. With the -m
option, jstack prints both Java and native frames of all threads along with the
'pc' (program counter). For each native frame, the closest native symbol to 'pc',
if available, is printed. C++ mangled names are not demangled. To demangle C++
names, the output of this command may be piped to c++filt.
I know frame is element of visual interface, but in this context it seems different?
Search in Google produce links to visual element. It seems that frame is about threading. Does it possible found definition? Thanks.
"frame" in this context refers to a stack frame, not a visual GUI element.
The short explanation is that every method call produces a stack frame, where local variables/results/return values are stored. By following the stack frames of your program, you can learn the current call stack
Here "frame" means stack frame, the parts of a program's call stack. http://en.wikipedia.org/wiki/Call_stack
Related
Background:
I want to log user activities on Eclipse, for example, what git repositories the users cloned, when did merge conflicts happened, and so on.
I came up with using the OpenJ9 -Xtrace option. First, to test the OpenJ9 -Xtrace option capabilities, I made the following options with OpenJ9: Xtrace Option Builder, and add these options to eclipse.ini to log cloned git repositories.
-Xtrace:none,maximal={mt{entry},mt{exit},mt{exception}},methods={org/eclipse/jgit/api/CloneCommand.setURI(),org/eclipse/jgit/api/CloneCommand.call()},output="C:\tmp\mytrace.trc"
-Xjit:exclude={org/eclipse/jgit/api/CloneCommand.setURI*|org/eclipse/jgit/api/CloneCommand.call*}
org/eclipse/jgit/api/CloneCommand.setURI() is a method to set a URI
for cloned repository in EGit/JGit.
org/eclipse/jgit/api/CloneCommand.call() is a method to clone the
specified repository.
Then I launched Eclipse with -clean option, clone a repository, and exit Eclipse.
I converted mytrace.trc with traceformat command, and got this output in mytrace.trc.fmt:
Trace Formatted Data
Time (UTC) Thread ID Tracepoint ID Type Tracepoint Data
07:56:41.541990300 *0x0000000001fafe00 mt.0 Entry >org/eclipse/jgit/api/CloneCommand.setURI(Ljava/lang/String;)Lorg/eclipse/jgit/api/CloneCommand; bytecode method, this = 0x7f9788a98
07:56:41.541991900 0x0000000001fafe00 mt.6 Exit <org/eclipse/jgit/api/CloneCommand.setURI(Ljava/lang/String;)Lorg/eclipse/jgit/api/CloneCommand; bytecode method
07:56:41.542010000 0x0000000001fafe00 mt.0 Entry >org/eclipse/jgit/api/CloneCommand.call()Lorg/eclipse/jgit/api/Git; bytecode method, this = 0x7f9788a98
07:56:46.512616000 0x0000000001fafe00 mt.6 Exit <org/eclipse/jgit/api/CloneCommand.call()Lorg/eclipse/jgit/api/Git; bytecode method
07:56:47.631399600 0x0000000001fafe00 dg.262 Debug ***** Thread termination - trace purged *****
This output shows setURI() method has an argument (Ljava/lang/String;), but there is no URI that JGit cloned.
Question:
How can I dump the content of method argument with OpenJ9 Xtrace option?
How can I dump the content of method argument with OpenJ9 Xtrace
option?
Your option only enables entry, exit, and exception method trace tracepoints. Method arguments are printed under a different tracepoint. If you use this option instead you should see the additional trace entries containing the arguments.
However, while the values of primitive arguments are shown in the trace, when the argument is an object you will only see the address of the object on the Java heap. For example, when tracing calls to *.println() you will see something like this:
15:31:13.710 0x33acc00 mt.18 - this: java/io/PrintStream#00000000FFF04AE0 method arguments: (java/lang/String#00000000E0002768)
My understanding is that the limitation is due to the architecture of the Xtrace engine, and the performance impact of resolving objects such as Strings and storing them in the trace buffers.
While addresses can be extremely useful for locating objects of interest in the Java heap, for example when using Eclipse Memory Analyzer to look at an associated system dump, Xtrace cannot provide the functionality you are aiming for.
A alternative approach would be to use a Java agent to modify (instrument) the org/eclipse/jgit/api/CloneCommand class at runtime to add logging code to the .setURI() method.
I'm developing a plug-in for the Eclipse platform. This plug-in will be used to give information about the line of Java source code currently being debugged.
When debugging a Java program, as you hit a breakpoint, Eclipse switches to the standard Debug perspective. Inside this perspective, apart from the standard Console output, the stack trace and various other views, you can see source code of the Java program currently being debugged. Inside this 'source code view', you can see a highlighted line, which is the line of code currently being debugged/evaluated. This highlighted line of code is what I want to access.
Assuming I know when the debugger is running (I assess that through a DebugBreakpointListener class that implements IJavaBreakpointListener), I need to 'ask questions' to the debugger. What, I imagine, I will need, is to somehow ask the debugger directly either for the line of code it is currently highlighting/debugging/evaluating or for the line number of the said line of code.
I'm making a static access to the JDIDebugModel to add the Java Breakpoint Listener:
JDIDebugModel.addJavaBreakpointListener(new DebugBreakpointListener);
I thought I could access the debugger with static references to JDIDebugPlugin but I've yet to find what I'm looking for.
At Part 3 of this research paper, the authors suggested that:
The Eclipse Java debugger is built upon the API of Java Debug Interface (JDI), which is part of the Java Development Toolkit. This API enables adding requests to monitor JVM events such as BreakpointEvent. When an event occurs, the debugger gets a notification and the thread in which this event took place can be obtained. For each frame in the stack trace of this thread the following information can be obtained:
• The source Java file in which the execution at this frame has taken place (or null if the source is not available).
• The method and line number (if available).
• The this object or null if the method is static.
The Eclipse debugger uses this information when a breakpoint is hit. It shows the stack trace for the suspended thread in the ”Debug” view. For the selected frame in this trace, Eclipse highlights the corresponding line number in its source file, and displays the this variable in the ”Variables” view.
This bulletpoint-listed things are exactly what I'm looking for.
Unfortunately, I can't find detailed documentation on how to 'plug in' to the debugger.
If someone can give me information, point me to information or a sample code, or maybe provide me with contact information of someone from the Eclipse JDI project, it would be immensely appreciated.
Thanks in advance.
------Update & Answer:------
With the help of greg-449's answer, I did exactly what I wanted to do. Here's what I did:
The aformentioned breakpoint listener I wrote implements the interface method breakpointHit, which is as follows:
#Override
public int breakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) {
System.out.println("Just hit a breakpoint!");
// Save pointers to the thread & breakpoint for future use.
return 0;
}
With the pointers to the thread and breakpoint objects saved in one of my objects, I could query them to get up-to-date information on the state of the frame stack, the thread and about the particular breakpoint that I've hit. I can get the namea dn path of the class the debugger is currently debugging by calling:
IStackFrame topStackFrame = thread.getTopStackFrame();
int debuggedLineNumber = topStackFrame.getLineNumber();
String debuggedClassPath = topStackFrame.getLaunch().getSourceLocator().getSourceElement(thread.getTopStackFrame()).toString();
This was exactly what I was looking for. I imagine I will need to read the source code files manually, run them through a tokenizer by having the 'newline' character as a delimiter and get the corresponding token to read that specific line.
There is a huge amount of information available in the IJavaThread and IJavaBreakpoint arguments passed to the breakpointHit method of the IJavaBreakpointListener which should contain this information.
I think for breakpoints which have a line number (not all do) the IJavaBreakpoint argument also implements ILineBreakpoint containing the line information.
I am writing part of a PHP web application (which will be used in a high school bug finding contest) where the user must find bugs in a given Java program. As a part of this, when the Java program executes, we want to highlight the lines of the source of the Java program where the code has executed. To do this, all we need are the line numbers of the source that have been executed, that is, the code path (or is it called code coverage?). We will highlight the lines in the source file using the line numbers.
We will be using PHP's shell-exec() to execute the Java program and the tool to get the code path (whatever that will be). What is the easiest way of getting the line numbers of code path?
Thank you very much!
Here is a picture that describes what we would like
PHP interperts the code, which means it runs over the source each time you run the program. This has the benefit of blowing up as the code is read (which makes line number printouts trivial); however, it often is expensive in other ways, as you cannot optimize deeply (or do any pre-runtime error checking).
Java compiles its code into a JVM assembly language called "bytecode." This means that what is running doesn't generally have access to (or even use) the source code. That said, there are techniques. A compiled Java class has the ability to add "extra data" and one of those "extra data elements" is a line number table, which is an index allowing someone running the assembly to "look up" the line number as the compiler recorded it.
This generally works ok, with the considerations that: compilers often don't mark up every instruction, the source code may not be available, optimization might make certain inner chunks of code not function in ways that facilitate pointing to the input code text.
How code coverage tools "fix" this is that they generally insert into the code (at the assembly level) a large number of commands that effectively act as logging statements to a format that allows the tool to determine which path through the code was actually followed. This is then mapped back through the line number table as best as possible and then used to highlight lines within the original source file.
If you want something with finer resolution (something that can process which portion of a line was executed) then you need to dig deeper. Eventually you might even consider writing your own compiler (or compiler extension) which will store your own custom line number table that overcomes the shortcomings of the current solutions.
Tricks like throwing exceptions (as Shiven has mentioned) and parsing out the line number do work; however, they pollute your code with odd exception processing for items that really aren't exceptional, just to "get the line number". Due to the code clutter and the generally poorer runtime performance of exceptions, I tend to avoid such solutions (but they do work).
Anyway, hopefully this will give you a view as to why it doesn't always work exactly the same way as PHP.
You could get a linenumber if you compile the program with the -g option, do a printStackTrace(), capture the trace output and extract the linenumber from there.
Take a look at Cobertura. It computes coverage and stuff like that, and if it doesn't already do it, it should be relatively easy to add the line number collecting to it.
There's a very hackish attempt to do that, but that's so slow that you may not be able to use it in production https://bitbucket.org/jowu/myriapod/wiki/Home
I have never done or seen anything like this but it does seem like an interesting problem. My thought would be to use the java debugger (jdb) to run the code, rather than just the java command.
You can step through the code line by line (via the step command in jdb) and each time a line executes its line number is spit out. This would require a little help from the PHP side (it would have to parse the line number as well as execute the next step command) but the line numbers are there. Here is a sample output from a very basic java program.
Java (TestClass.java)
public class TestClass {
public static void main(String[] args) {
System.out.println("foo");
System.out.println("bar");
}
}
jdb (jdb TestClass after running javac TestClass.java)
Initializing jdb ...
> stop at TestClass:3
Deferring breakpoint TestClass:3.
It will be set after the class is loaded.
> run
run TestClass
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
>
VM Started: Set deferred breakpoint TestClass:3
Breakpoint hit: "thread=main", TestClass.main(), line=3 bci=0
3 System.out.println("foo");
main[1] step
> foo
Step completed: "thread=main", TestClass.main(), line=4 bci=8
4 System.out.println("bar");
main[1] step
> bar
Step completed: "thread=main", TestClass.main(), line=5 bci=16
5 }
main[1] step
>
The application exited
Try referring to this link JVMDI
You can try accessing the values of the program counter and then map it onto the lineNumberTable .
OR
I think JVMDI has a method which can access the line number of the executing code.I'm not sure of the latter,refer the to the link above and hope it helps.
how can i find out which class/method has called the actual method?
You could try to create an exception to get its stacktrace.
Throwable t = new Throwable();
StackTraceElement[] stackTraceElements = t.getStackTrace();
Now stackTraceElement[0] contains the caller of the current method.
But beware (from Throwable.getStackTrace()):
Some virtual machines may, under some
circumstances, omit one or more stack
frames from the stack trace. In the
extreme case, a virtual machine that
has no stack trace information
concerning this throwable is permitted
to return a zero-length array from
this method. Generally speaking, the
array returned by this method will
contain one element for every frame
that would be printed by
printStackTrace.
Here's one way that I've used:
StackTraceElement element=Thread.currentThread().getStackTrace()[3];
String className=element.getClassName();
String methodName=element.getMethodName();
[3] is hardcoded because:
[0] is Thread.dumpThreads()
[1] is Thread.getStackTrace()
[2] is the current method
[3] is the one before the current method
A faster but non-portable solution is to use the following. It does not create a stack trace and just gives you the information you need. However, not all JVMs will have this and future version of Java might not either.
Class callerClass = sun.reflect.Reflection.getCallerClass(2);
You can print a stack trace to do this.
If you want to do this dynamically, I'm not really sure if this is possible (aside from printing and parsing a stack trace dynamically).
You could use a debugger, or a profiler. Netbeans has both, but a lot of other options exists.
Else, if you can modify the code you can throw a new exception() and have a stacktrace printed in the console.
To echo and elaborate on matt b and yishai's comments:
If you are doing this because you are writing a logger or maintaining trace information or some such, okay, cool. I've used stack traces in production code exactly once, and even that was really a debugging issue: We had a problem with database connections not being properly closed, so I modified the "get database connection" function to save the identity of the caller, and then had a periodic sweep to look for dead connections and see where they had been created.
Java's built-in logging function does stack traces so it can write who called the logger to the log file. I worry about the overhead of this as I understand that stack traces are expensive, but whatever.
But if you're doing this because your function is going to behave differently depending on where it was called from, like "if called from class X update customer data else if called from class Y update employee data" or something like that: Really really bad idea. Pass a parameter or write separate functions.
I'm currently working on a Java project and was having a problem with a stack overflow error. What happens is first the program reads in a file of about 1,500,000 words and adds it to an array. It then reads in a small file of about 600 words and adds it to an array. It checks how many words in the 600 word file occur in the other file. Each word in the big file is associated with a number. So when it finds a word in the big file it takes a copy of the word and its associated integer and adds it to an array. My problem is that I am getting a stack overflow error:
"AWT-EventQueue-0" java.lang.StackOverflowError
The thing is that when the small file is about 200 words the program runs fine.
The last line the program has to execute is:
result.setPage("file:file for gui NEW.html");
(where result is an JEditorPane)
For some reason I get a stackoverflow error when the small file is 600 words but runs ok when it is 200 words. It runs the last line and produces this file but doesn't print it to the editor pane as that is when the exception kicks in.
Can anyone help to tell me why this may happen and how I could go about fixing it?
Thanks.
The error in the console in full is:
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source)
at sun.awt.SunToolkit.getSystemEventQueueImpl(Unknown Source)
at java.awt.Toolkit.getEventQueue(Unknown Source)
at java.awt.EventQueue.isDispatchThread(Unknown Source)
at javax.swing.SwingUtilities.isEventDispatchThread(Unknown Source)
at javax.swing.JComponent.revalidate(Unknown Source)
at javax.swing.plaf.basic.
BasicTextUI$RootView.preferenceChanged(Unknown Source)
at javax.swing.text.View.preferenceChanged(Unknown Source)
at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
at javax.swing.text.View.preferenceChanged(Unknown Source)
at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
at javax.swing.text.View.preferenceChanged(Unknown Source)
at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
(... repeating forever ...)
EDIT: So basically it seems that two controls in the GUI keep invoking each other's preferenceChanged() method.
The Gui seems like the most likly cause because when I run the program without the gui and print the contents of the file to the console instead it works fine. I've no idea what is actually causing the problem. I'm not using preference changed routine. Only thigs like setSize(), setVisible() etc. would that cause it?
Do you have a recursive function somewhere? This is usually the source of stack overflows.
Additional info here.
I think you have ran into a variation of this issue:
http://www.jdocs.com/harmony/5.M5/javax/swing/text/BoxView.html#M-layout(int,int)
protected void layout ( int width, int height )
This method may cause stack overflow
if upon each layout try a child
changes its preferences, i.e.
preferenceChanged is called.
I'm not sure how you managed do achieve this but try to not to change prefences of childs on layouts. I'm sure that someone with more experience with swing than me could provide a more valuable answer.
The stack overflow is in a GUI object's preferenceChanged() routine. The culprit is something your GUI is doing, your array usage is just the trigger.
Are you subclassing any GUI objects, especially one with your own preferenceChanged() function anywhere? Best guess is that it has something to do with displaying a scrollbar, since the exception depends on how many objects you're adding to this array. Check the docs very carefully for any GUI objects or events that you are working with.
Look at the stacktrace of the StackOverflowError. It will almost certainly show you one or two methods repeatedly calling itself/each other. Rewrite those methods so that this does not happen (or does not happen that often).
I would check the file that's being output since the recursion seems to be happening in the JEditorPane rather than in your code - does this file show up in a normal web browser okay? Keep in mind the the JEditorPane is not the most advanced component in the world and may choke if you're trying to show something complex.
I've also experienced layout errors in JEditor Pane which occur seemingly at random and I've never found the bottom of, although this is usually when I'm editing the contents of the pane rather than just showing a web page.
If you're changing the size of the window whilst you're loading the file it may cause the kinds of errors that you're describing - I would try and just load the file into the editor pane without altering it.
Assuming you can attach a debugger, on Eclipse (sorry, I don't know Netbeans/Idea) you can then add an exception breakpoint for StackOverflowError. In the breakpoint view's toolbar, there is a button which has a blue J with an exclamation mark - "J!" - click this, then enter StackOverflowError and choose to suspend on uncaught exceptions only.
Perhaps this will provide some more context as to what is going wrong.
If it is a recursion issue then you can try to change your algorithm with a new one that uses an explicit stack instead of an implicit stack like BFS or DFS
You should check for recursion - both direct recursion (when a function calls itsself) and indirect recursion (when A calls B and B calls A again).
The easiest way to do this is to attach a debugger and look at the call stack at the moment you've got stack overflow.