Software Archive
Read-only legacy content
17061 Discussions

Finding Memory Errors in Java JNI DLL

David_Eisner
Beginner
861 Views

I'm evaluating Intel Parallel Inspector 2011 (PIN) with Visual Studio (VS) 2008. I'm trying to find memory errors in a DLL that provides native JNI methods to a Java application (JDK 6), but I'm having some difficulty.

My understanding is that in order to analyze a DLL using PIN, it's necessary to specify a target .exe that loads the DLL. So I wrote a simple Java console app that exercises the DLL and packaged it into a JAR file that can be executed with "java.exe -jar MyTestApp.jar". I have my DLL in the same directory as the java.exe I'm using.

In the VS debug configuration I have 'C:\\path_to\\java.exe' set for the command and '-jar C:\\path_to\\MyTestApp.jar' for the arguments. I start the PIN inspector analysis, the java app runs to completion, and I get a report about Memory Errors. However, my DLL is not listed, only these:

java.dll, java.exe, jvm.dll, msvcr71.dll, ntdll.dll, and zip.dll

I added an intentional bug to my DLL (reading an uninitialized automatic variable), but the bug isn't discovered. I thought perhaps the C compiler's basic runtime checks might be hiding the error (it discovered the bug and brought up a warning dialog at runtime), so I dialed the runtime checks down to 'Default'. It no longer warns me about my intentional bug, but PIN still does not detect it.

What am I doing wrong? Thanks!

0 Kudos
11 Replies
Kirill_R_Intel
Employee
861 Views
David,

Intel Parallel Inspector doesn't support analyzing of child processes. You can only analyze the target process. Moreover, Java is not supported.
Intel Inspector XE is a more featured variant. It can analyze child processes. However Java is not supported as well. You may try it, but there is no any garantee that the tool will be able to locate your dll.

Regards,
Kirill
0 Kudos
David_Eisner
Beginner
861 Views

Kirill,

Thanks for the response. Java JNI code does not run inside a child process -- it runs in the same process as the java.exe executable. And it is not Java bytecode. Rather, it's native code, written in C/C++ (or assembly) which is compiled into a standard PE32 DLL (using e.g. Visual Studio's C compiler). This DLL is loaded at runtime by the native java.exe process.

Or to put it another way, java.exe is just a native C program using LoadLibrary() to load my DLL when the java bytecode it's interpreting tells it to do so.

-David

0 Kudos
SergeyKostrov
Valued Contributor II
861 Views
Quoting David Eisner
...Rather, it's native code, written in C/C++ (or assembly) which is compiled into a standard PE32 DLL (using e.g. Visual Studio's C compiler).

Do you have thesource codes for the DLL?

I simply would like to understand if this is your own DLL, orfrom some 3rd-partywithout the source codes.

Best regards,
Sergey
0 Kudos
Kirill_R_Intel
Employee
861 Views
Yes, Java loads dll in it's process, but it's not supported, there possible some drawbacks. Can you attach your test reproducer to the thread, so I we can play with it and look what's wrong?
0 Kudos
SergeyKostrov
Valued Contributor II
861 Views
Hi everybody,

I'd like to make a little correction:

Quoting Kirill Rogozhin (Intel)
...Java loads dll in it's process...

...Java loadsdll in its address space...

Best regards,
Sergey
0 Kudos
David_Eisner
Beginner
861 Views

Sergey,

Neither -- it's 3rd-party but with the source code. It's the RXTX library an open source Java library for serial and parallel port communication:http://rxtx.qbang.org/wiki/index.php/FAQ

-David

0 Kudos
David_Eisner
Beginner
861 Views

Kirill,

Thanks for taking the time to look at this. I'll try to post something soon, either today or tomorrow.

-David

0 Kudos
David_Eisner
Beginner
861 Views

I've attached a zip file containing a Visual Studio 2008 project for the DLL code, and a Netbeans project for the Java class, CommTest.java, which uses the RXTXcomm.jar library (which itself uses the JNI rxtxSerial.dll). As I mentioned, the PIN configuration runs 'java.exe -jar C:\path_to\CommTest.jar'. I've also included a Netbeans project for the RXTXcomm.jar library, but you don't really need that. The CommTest.jar in PIN Example/Netbeans/CommTest/dist/ is setup to load the already-compiled RXTXcomm.jar from the lib/ subdirectory.

In the DLL code, I've introduced an intentional bug in termios.c, at the beginning of serial_test() that does an uninitialized variable read, something I assume PIN should catch.

If this is too complicated, let me know and I can try to generate a simpler JAR/DLL that illustrates the problem.

Thanks again.

0 Kudos
SergeyKostrov
Valued Contributor II
861 Views
Quoting David Eisner
...it's 3rd-party but with the source code...

As a compromiseyou coulduse MFC-based Memory Leaks detection with a report to an external txt-file.

I'll prepare a Test-Case on how to do it. Would it help?

Best regards,
Sergey
0 Kudos
SergeyKostrov
Valued Contributor II
861 Views
Quoting David Eisner
...it's 3rd-party but with the source code...

As a compromiseyou coulduse MFC-based Memory Leaks detection with a report to an external txt-file...


The following piece of code could be used to enable MFC-based Memory Leaks detection:

[cpp] ... RTtchar *g_pszMemLeaksReportLog = RTU("C:\MemLeaksReport.log"); ... RThandle hLogFile = RTnull; _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG ); hLogFile = ::CreateFile( g_pszMemLeaksReportLog, GENERIC_WRITE, FILE_SHARE_WRITE, RTnull, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, RTnull ); if( hLogFile == RTnull ) return; _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, hLogFile ); _RPT0( _CRT_WARN, "Processing startedn" ); ... [/cpp]
It is configured tocreate areport( external file )and here is example of how it looks like:

...
Processing started
virtual CTest::~CTest()
virtual CTest::~CTest()
virtual CTest::~CTest()
virtual CTest::~CTest()
virtual CTest::~CTest()
virtual CTest::~CTest()
virtual CTest::~CTest()
virtual CTest::~CTest()
Detected memory leaks!
Dumping objects ->
..\common\prttests.cpp(5943) : {91} normal block at 0x041B0040, 4194304 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
..\common\prttests.cpp(5943) : {89} normal block at 0x03DA0040, 4194304 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
..\common\prttests.cpp(5943) : {87} normal block at 0x03990040, 4194304 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
..\common\prttests.cpp(5943) : {85} normal block at 0x03580040, 4194304 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
..\common\prttests.cpp(5943) : {83} normal block at 0x03170040, 4194304 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
..\common\prttests.cpp(5943) : {81} normal block at 0x02D60040, 4194304 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
..\common\prttests.cpp(5943) : {79} normal block at 0x02950040, 4194304 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
..\common\prttests.cpp(5943) : {77} normal block at 0x02140040, 4194304 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
Processing Completed
...
0 Kudos
SergeyKostrov
Valued Contributor II
861 Views
Here is updated set of codes you could use:

[cpp] // Header files ... #define CRTDBG_MAP_ALLOC #include #include ... // Initialization ... TCHAR *g_pszMemLeaksReportLog = _T("C:\MemLeaksReport.log"); ... HANDLE hLogFile = NULL; _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_DEBUG ); hLogFile = ::CreateFile( g_pszMemLeaksReportLog, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if( hLogFile == NULL ) return; _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, hLogFile ); _RPT0( _CRT_WARN, "Processing startedn" ); ... // Your processing... // Final cleanups ... _CrtDumpMemoryLeaks(); _RPT0( _CRT_WARN, "Processing Completedn" ); if( hLogFile != NULL ) { ::CloseHandle( hLogFile ); hLogFile = NULL; } ...[/cpp]

These libraries should be used ( Debug versions )

msvcrtd.lib
msvcurtd.lib if Unicode Character Set is used

0 Kudos
Reply