I built a (customized) 1.8 HotSpot VM in Netbeans 7.2 using GDB 7.4 which works for executing Java programs. I want to debug a SIGSEGV that the program produces by calling a native function called by JNI that corrupts an object header.
However, I have some problems debugging the HotSpot VM: I have several breakpoints before the call to the main function in java.c. Sometimes, they trigger and sometimes the main function executes without all the breakpoints halting before. The most far I can get is
/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
After that, a step-in runs through the whole Java program, eventually triggering the SIGSEGV. The call is leading to the JNI API so I included the "hotspot/src/share/vm/prims" directory to the source dirs in the debug section. However, I could not see any effect. Does anybody have an idea how I can step into the C++ method calling the Java main method?
When the SIGSEGV causes the Netbeans debug view to stop, the call stack shows the expected call stack. However, instead of the C++ code it just shows assembler code while displaying the names of the C++ classes. The initial caller is "?? ()". Is there some way to see the C++ code or do I have to manually map the assembler code to the C++ code? I read a great article by Volker Simonis where he describes that such unknown frames relate to generated code. However, I'm still puzzled that the consecutive caller frames show class and method names. Is it a problem with source lookup or simply relates to the first unknown frame?
Did you compile hotspot in debug mode, i. e. make all_debug? If hotspot is optimised than code may be run in different order than it's in source file, and some symbols can be stripped out, preventing debugger to give you meaningful info, or setting a breakpoint.
Related
As far as I know, the compiler compiles the code by converting it to a language that a computer can understand which is the machine language and this is done before running the code.
So, does the compiler compile my code each time I write a character in the file?
And if so, does it check the whole code? Or just the line that updated.
An important part to this question is the type of programming language(PL) we are talking about. Generally speaking, I would categorize PL into 3 groups:
Traditional PLs. Ex: C, C++, Rust
The compiler compiles the code into machine language when you hit the "build" button or the "run" button.
It doesn't compile every time you change the code, but a code linter does continuously observe your code and check it for errors.
Another note, when you change part of the code and compile it, the compiler doesn't recompile everything. It usually only recompile the current assembly file (or module or whatever you call them).
It is also important to note that a lot of modern IDEs, compile when you save the files.
There is also the hot reload feature. It is a smart compiler feature that can swap certain parts of the code while it is running.
Interpreted PLs Ex: python, JS and PHP
Those languages never get compiled; Rather, they get interpreted or translated into native code on the fly and in-memory when you run them.
Those languages usually employee a cache to accelerate the subsequent code execution.
Intermediary Code PL. Ex: Kotlin, java, C#
Have 2 stages of compilation:
Build time compilation.
Just in time (run-time) compilation.
Build time compilation converts the code into intermediary language (IL) machine code, which is special to the run-time.
This code only understood by the run time like Java runtime or dot net runtime
The second compilation happens when the programs get installed or ran for the first time. This is called just in time compilation (JIT)
The run-time convert the code into native code specific to the run-time OS.
We've recently upgrade our Application to run under Java 11 (used to be Java 8).
There is one panel on our apps main screen that Files can be dropped onto.
This works fine on Windows but not on OSX. (used to work under Java 8, failed after switching to Java 11).
A file can be dragged from another Java application that supports it, but NOT from Finder.
The TransferHandler.canImport() method is never called.
The DropTarget.dragOver() method IS called, but the drop() method is never called. I can't trace into runtime library methods, as it doesn't have line number information.
I've found that I CAN drag files from Finder to another Java app, or to a JDialog in our main app.
It only fails if the JTable is in a panel in our main application window. So our app must be doing something odd to cause it to fail.
The problem is finding out WHY it fails, only on OSX. This is a LARGE application, and the main window is quite complex. Posting a Self Contained source example is impossible - especially since the simple case works.
What I could REALLY use is a Java 11 Runtime library that has line number information so I can step into it. Yes, I have the full source that came with the Java 11 JDK. (Adopt OpenJDK) I've been unable to get it to compile under Eclipse.
Any suggestions on what our app could be doing to cause this to fail? Or where I can find a Debug Java 11 runtime library?
Sure would have been nice to have a Debug runtime library.
The issue is that on the calls to DropTarget.dragEnter() and .dragOver(), the data in the Transferable and the getCurrentDataFlavors() is invalid on OSX.
getCurrentDataFlavors() will return a list of ALL data flavors - none of which will have any transferData. (this means that the data is also invalid in all the calls to TransferHandler.canImport() as well.)
The ONLY time the data is valid is in the TransferHandler.importData() call.
Our code was checking to see that the user was dragging a file of the correct type in the canImport() call. Since all the data is now invalid (OSX, Java 11) that call was throwing an NPE (since the getCurrentDataFlavors() included our desired flavor, but the getTransferData(flavor) return null. Note that this worked correctly with Java 8.
Combine that with the Runtime drag handling code that silently ignores exceptions, well, not quite ignores them, it disables all further Drop operations on that target when one happens. That makes it really difficult to track down what is happening.
I compiled my application with debug symbols using clang. When attaching to the application using lldb and stepping into, for example, __cxa_throw, I don't see the source code of libc++abi.dylib. What am I doing wrong?
You do get some debug information for the STL, because a lot of the STL code is in header files that get compiled into your application. But you don't have debug information for the code that is actually compiled into libc++abi.dylib, since Apple doesn't distribute dSYM's for system libraries. __cxa_throw is actually a function in the library.
As a separate issue, because most people don't actually want to step into STL code, lldb has a setting:
(lldb) set show target.process.thread.step-avoid-regexp
target.process.thread.step-avoid-regexp (regex) = ^[^ ]+ std::|^std::
that will cause stepping to artificially step over code from the STL. You can undo this by setting that value to "". That will get you into the inlined code when stepping.
My intetion is to debug the called cobol program aswel.
But not sure how to keep a break point to go inside the called cobol program.
At the moment i am able to debugg the main cobol program and control just goes over the called copbol program.Thanks
Considering that it is Cobol on a Mainframe and that you already accessed the debugger, I guess the issue is with the compilation of the called program.
Usually, programs that are called by a program in debugger are jumped over (they run, but you can't see code or control them) if you forget to compile the called program with debugger option.
The same way you compiled your program with DEBUG option, you can compile the called program. This usually is done with a 'D' option at the compilation screen.
Let me know if this works.
Are you building the called subprogram in the same RD/z project? That can make a difference. Otherwise, you will need to use the mainframe side of things to point your debug info back at your workstaions IP address either via the LE TEST() parameter on the parm string or by linking in a custom CEEINIT to specify those parms.
Compilation of my code in both modes debug and release is successful. Debug mode execute and works fine, but when i execute release mode, it says "the application was unable to start correctly 0x80000003".
What is this error and why debug mode works fine but not release.
DLLs for debug and release are present in the same directory name "bin". "lib" for both modes also placed in the same directory.
I tried to solve it many ways but not succeeded ? Guide me how to solve this issue? Thanks.
why debug mode works fine but not release
Thre can be many reasons why one build works while another doesn't. The shape and size of data structures can be different because of #ifdef or because the compiler emits different code, the code being executed can be different - again because of constructs like #ifdef or because of the code the compiler is emitting.
That can matter when you've got code with a bug in it. Let's say you've got a bug that miscalculates the length of an array (or the size of a structure or whatever). You do some pointer arithmetic and write some data into memory using that pointer - only you're writing to the wrong place. Whether that mistake breaks your program may depend on what was in the memory you overwrote.
If you're lucky your program crashes almost immediately because what you overwrote was important to some code executed immediately after your bug. If you're only a little bit lucky your program crashes some time later in a completely different part of your program because what you overwrote was important to code far away from your bug. If you're really unlucky your program doesn't crash at all until several years later when a completely unrelated change moves things around in memory so now what you are overwriting suddenly is important.
There are lots of other possible causes of what are sometimes called Heisenbugs
What is this error
One place to look for errors like 0x80000003 is the file WinError.h which you'll find in the SDK you are using (either the one that came with Visual Studio 2010 or one you installed later). Look in WinError.h and you'll find that that E_INVALIDARG is defined to be _HRESULT_TYPEDEF_(0x80000003L).
That doesn't necessarily help though because we we don't know enough about what is returning that error or why it is returning that error or even that your 0x80000003 is in fact an E_INVALIDARG - it could be some other error with the same value, or some piece of code mis-using E_INVALIDARG or something else.
Another possibility is that 0x80000003 is a hard-coded breakpoint exception being thrown - most likely because your program has got to one of those "this should never happen" places where the only thing that makes sense is to throw an exception and crash. If you look in NtStatus.h (in the same place as you found WinError.h) you'll find that STATUS_BREAKPOINT is defined to be ((NTSTATUS)0x80000003L)
how to solve this issue
The trick is to figure what is causing the 0x800000003 (and where in your code it is happening) so you can narrow down why it is happening. Most likely it's an exception but why jump to conclusions?
You can run a release build inside the debugger just as you would run a debug build - that is, build the code using the Release target and then press F5 or Debug | Start Debugging. Look in the Output Window and you may see some information that will help you interpret the error.
You can also use the Debug | Exceptions menu to add a new Win32 Exception with the value 80000003 and set that up to break when thrown rather than to break when unhandled. That way you should stop in the debugger when that exception is thrown (if it is in fact thrown).
Of course it could be that even running your program within a debugger is enough to change things so your problem doesn't occur.