3

JRE version: 6.0_45-b06 Java VM: Java HotSpot(TM) Client VM (20.45-b01 mixed mode, sharing windows-x86 )

Hi,

We have a java application that periodically crashes (and apparently has been doing so for years). It uses native code (.cpp) on Windows. Here is the top of the stack from one of the hotspot error logs:

--------------- T H R E A D ---------------

Current thread (0x002a6c00): JavaThread "main" [_thread_in_vm, id=4168, stack(0x00640000,0x00690000)]

siginfo: ExceptionCode=0xc0000005, reading address 0xcccccccc

Registers:
EAX=0xcccccccc, EBX=0x0068fa2c, ECX=0x0068f940, EDX=0xcccccccc
ESP=0x0068f900, EBP=0x0068f900, ESI=0x002a6c00, EDI=0x002a6d28
EIP=0x6da12c06, EFLAGS=0x00010286

Top of Stack: (sp=0x0068f900)
0x0068f900:   0068f91c 6d8fe0d1 cccccccc 002a6d28
0x0068f910:   002a6c00 0068fa2c 0068f940 0068f934
0x0068f920:   6d8fe1a5 0068f940 cccccccc 002a6c00
0x0068f930:   002a6c00 0068f960 6d973a71 cccccccc
0x0068f940:   002a6c00 0068f9c0 0068f970 0068fa2c
0x0068f950:   002a6c00 002a75e0 0000026d 6db0848c
0x0068f960:   0068f9c0 042307a2 002a6d28 cccccccc
0x0068f970:   0068fa2c 04290e18 0068fa2c cccccccc 

Instructions: (pc=0x6da12c06)
0x6da12be6:   24 c0 3c 80 75 01 4f 41 3b ca 7c f1 5e 8b c7 5f
0x6da12bf6:   5d c3 cc cc cc cc cc cc cc cc 55 8b ec 8b 55 08
0x6da12c06:   8a 0a 33 c0 84 c9 74 13 8b ff 80 e1 c0 80 f9 80
0x6da12c16:   74 01 40 8a 4a 01 42 84 c9 75 ef 5d c3 cc cc cc 


Register to memory mapping:

EAX=0xcccccccc is an unknown value
EBX=0x0068fa2c is pointing into the stack for thread: 0x002a6c00
ECX=0x0068f940 is pointing into the stack for thread: 0x002a6c00
EDX=0xcccccccc is an unknown value
ESP=0x0068f900 is pointing into the stack for thread: 0x002a6c00
EBP=0x0068f900 is pointing into the stack for thread: 0x002a6c00
ESI=0x002a6c00 is a thread
EDI=0x002a6d28 is an unknown value

Stack: [0x00640000,0x00690000],  sp=0x0068f900,  free space=318k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [jvm.dll+0x132c06]
V  [jvm.dll+0x1e0d1]
V  [jvm.dll+0x1e1a5]
V  [jvm.dll+0x93a71]
C  [MSWordCOMBatch.dll+0x107a2]  Java_com_ams_cnl_common_MSWordCOMBatch_connectToWord+0xf239
C  [MSWordCOMBatch.dll+0xfceb]  Java_com_ams_cnl_common_MSWordCOMBatch_connectToWord+0xe782
j  com.ams.cnl.common.MSWordCOMBatch.addDocument(Ljava/lang/String;)Ljava/lang/String;+0
j  com.ams.cnl.common.CNLBatchPrintProcess.printSingleTemplateLetters(Ljava/util/ArrayList;Ljava/lang/String;IIZ)V+338

I disassembled MSWordCOMBatch.dll using the instructions provided here:

https://weblogs.java.net/blog/kohsuke/archive/2009/02/crash_course_on.html

The image base is 10000000. Here is the assembly from the 100107A2 offset.

Offset 100107A2

100107A2: 3B F4              cmp         esi,esp
100107A4: E8 47 43 00 00     call        10014AF0
100107A9: 5F                 pop         edi
100107AA: 5E                 pop         esi
100107AB: 5B                 pop         ebx
100107AC: 83 C4 44           add         esp,44h
100107AF: 3B EC              cmp         ebp,esp
100107B1: E8 3A 43 00 00     call        10014AF0
100107B6: 8B E5              mov         esp,ebp
100107B8: 5D                 pop         ebp
100107B9: C2 04 00           ret         4

Offset 10014AF0

10014AF0: 75 01              jne         10014AF3
10014AF2: C3                 ret

Offset 10014AF3

10014AF3: 55                 push        ebp
10014AF4: 8B EC              mov         ebp,esp
10014AF6: 83 EC 00           sub         esp,0
10014AF9: 50                 push        eax
10014AFA: 52                 push        edx
10014AFB: 53                 push        ebx
10014AFC: 56                 push        esi
10014AFD: 57                 push        edi
10014AFE: CC                 int         3
10014AFF: 5F                 pop         edi
10014B00: 5E                 pop         esi
10014B01: 5B                 pop         ebx
10014B02: 5A                 pop         edx
10014B03: 58                 pop         eax
10014B04: 8B E5              mov         esp,ebp
10014B06: 5D                 pop         ebp
10014B07: C3                 ret

Second connectToWord frame Offset 1000FCEB

1000FCE6: E8 E5 15 FF FF     call        100012D0
1000FCEB: 8B 4D F4           mov         ecx,dword ptr [ebp-0Ch]
1000FCEE: 64 89 0D 00 00 00  mov         dword ptr fs:[00000000h],ecx
        00
1000FCF5: 5F                 pop         edi
1000FCF6: 5E                 pop         esi
1000FCF7: 5B                 pop         ebx
1000FCF8: 83 C4 60           add         esp,60h
1000FCFB: 3B EC              cmp         ebp,esp
1000FCFD: E8 EE 4D 00 00     call        10014AF0
1000FD02: 8B E5              mov         esp,ebp
1000FD04: 5D                 pop         ebp
1000FD05: C2 0C 00           ret         0Ch

Offset 10014AF0

10014AF0: 75 01              jne         10014AF3
10014AF2: C3                 ret

offset 10014AF3

10014AF3: 55                 push        ebp
10014AF4: 8B EC              mov         ebp,esp
10014AF6: 83 EC 00           sub         esp,0
10014AF9: 50                 push        eax
10014AFA: 52                 push        edx
10014AFB: 53                 push        ebx
10014AFC: 56                 push        esi
10014AFD: 57                 push        edi
10014AFE: CC                 int         3
10014AFF: 5F                 pop         edi
10014B00: 5E                 pop         esi
10014B01: 5B                 pop         ebx
10014B02: 5A                 pop         edx
10014B03: 58                 pop         eax
10014B04: 8B E5              mov         esp,ebp
10014B06: 5D                 pop         ebp
10014B07: C3                 ret

Here is the code from MSWordCOMBatch.cpp:

#include <afx.h>
#include <Afxdisp.h>
#include <Afxwin.h>
#include <comdef.h>
#include "com_ams_cnl_common_MSWordCOMBatch.h"
#include "MSWordCOMBatch.h"
#include <winspool.h>
#include <Winuser.h>
#include <Windows.h>

int miConnectOption;
char* msTemplateDir = NULL;
bool mbWordWasRunning;
bool mbOpen;
bool mbLoadPrintDuplex = false;
ApplicationPtr moWord;
_DocumentPtr moDoc;

/* other methods not included, can provide as needed */

/**
 * connectToWord()
*/
void connectToWord(int fiOption, char* fsTemplateDir)
{   
    miConnectOption = fiOption;
    msTemplateDir = fsTemplateDir;

    mbWordWasRunning = false;
    mbOpen = false;

    if (moDoc != NULL) moDoc.Release();
    if (moWord != NULL) moWord.Release();

    // Create word object
    if (mbOpen == false)
    {
    moWord.CreateInstance("Word.Application");
    mbOpen = true;
    miConnectOption = 1;
}

    return;
}

The problem is that I do not know assembly, or cpp. :) I am having a hard time translating the assembly to cpp.

Any help you can provide is greatly appreciated. Thanks!

Al Beback
  • 31
  • 2
  • 1
    If you don't know C++ I'm not sure how the painstaking effort of someone translating the assembly to C++ would help you? – Jonathan Mee Jan 21 '15 at 18:06
  • This C++ snippet is not very impressive. Global variables. No exception handling. No support for Unicode directory names. Possible access to variable in undefined state (uninitialized or leaking memory) in `moWord`, `moDoc`. Assembly listing and the log don't indicate what exactly went wrong (registers missing). If you are supposed to maintain the application it looks like good opportunity to rewrite some code into more maintainable shape, see [Stack Overflow: Word document creation API in Java](http://stackoverflow.com/questions/1991030/word-document-creation-api-in-java) for some inspiration – xmojmr Jan 21 '15 at 19:58
  • Added the register information from the log. Also added more from the .cpp file to give you a sense of how old the code is. Thanks. – Al Beback Feb 17 '15 at 20:39

1 Answers1

0

What you're getting is an Unhandled Exception 0xc0000005 - Access Violation. Your disassembled code is really pointless. Sorry. It shows only entry to the standard Windows SEH - Structured Exception Handling. It's purpose is to show you a fancy dialog with error code.

I'm pretty much sure your problem is that

moWord.CreateInstance("Word.Application");

generates a null pointer exception in some cases.

if (moWord != NULL) moWord.Release();

// Create word object
if (mbOpen == false)
{
    moWord.CreateInstance("Word.Application");

Here you first check if object exists and then release it. But you never get the object if it doesn't exist.

Alexander Zhak
  • 9,140
  • 4
  • 46
  • 72