3

Wondering what this exception is about?

NTUnhandledExceptionHandler@NTExceptionHandler@@CGJPAU_EXCEPTION_POINTERS@@@Z! jdenet_k.exe?

=====Call stack of thread 5612=====
_LogNTCallStackDump@8! jdel.dll  
?NTUnhandledExceptionHandler@NTExceptionHandler@@CGJPAU_EXCEPTION_POINTERS@@@Z! jdenet_k.exe  
0x78c65b6.<nosymbols>! qstatus.dll  
0x771bd29e.<nosymbols>! ntdll.dll  
0x771bd45f.<nosymbols>! ntdll.dll  

====> Exception C0000005 ACCESS_VIOLATION occurred in thread 5612 with call stack:
_jdeStrcmp@8! jdeunicode.dll  
_IB4210030_SetCrossReferenceItemData@20! CSALES.dll  
_IB4210030_ReconcileSalesOrderLineData@24! CSALES.dll  
_IB4210030_IProcessSalesOrderLine@20! CSALES.dll  
_IB4210030_ProcessNextUnprocessedSalesOrderLine@20! CSALES.dll  
_ProcessNextUnprocessedSalesOrderLine@20! CSALES.dll  
_IB4210900_ProcessUnprocessedLines@12! CSALES.dll  
_IB4210900_PerformSalesOrderAction@32! CSALES.dll  
_SalesOrderApplCtrlEX@12! CSALES.dll  
_jdeCallObjectV2@44! jdekrnl.dll



There is also another related error in one of the log files:

====> Exception C0000005 ACCESS_VIOLATION occurred in thread 5612
call stack dumped in file <E:\JDEdwards\E812\DDP\log\jde_11740_1310990285_1_dmp.log>: iParam: 0000000000
INFO: Entering kernel signal handler, process exiting soon: iParam: 1310990289
INFO: Done setting IPC Handle State structures to abandoned, process exiting immediately: iParam: 1310990289
CloudEagle
  • 65
  • 1
  • 8
  • 3
    I'm going to guess "a bug in the program ... somewhere". –  Aug 24 '11 at 19:46
  • 2
    You have an [access violation](http://en.wikipedia.org/wiki/Access_violation), likely because you're passing an invalid pointer to `jdeStrcmp()`. Maybe if you posted some code, someone who isn't a psychic could figure it out. – Adam Rosenfield Aug 24 '11 at 19:52
  • Q: did you resolve the problem? Can you modify function SetCrossReferenceItemData() in CSALES.DLL, or have you contacted your vendor for a patch update? – paulsm4 Aug 25 '11 at 18:33

2 Answers2

1

emphasized textIt looks as if the function jdeStrcmp() (stdcall function) in jdeunicode.dll caused an exception (an access violation, in other words, some pointer was bad or nil).

In my opinion, a good DLL won't let an exception escape, but apparently this one did.

Update

Letting an exception escape is usually no problem for a caller that was written in the same language as the DLL. It can be disastrous for a caller that was not. I speak from experience here. The function should of course somehow signal the caller that something happened. How that happens is a matter of design. Letting exceptions escape is certainly the wrong way.

See this SO question too, about exceptions crossing module boundaries. Or this one (same language, different version!). Or google for it. You'll see many reasons and examples of why exceptions crossing module boundaries are a Bad Idea(tm).

One example of a language that can't catch exceptions that escape a (native) DLL is C#, e.g. in this SO question. I assume the same applies to other .NET languages, as well as a score of native languages.

Community
  • 1
  • 1
Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94
  • 1
    What should a `Strcmp()` function do if it's given a bad pointer or the data the pointer points to is corrupted? – Michael Burr Aug 24 '11 at 20:24
  • It should capture any exceptions and end gracefully. As I said, exceptions should never leave a DLL, especially since the caller outside the DLL may not be able to handle the exceptions raised inside the DLL. – Rudy Velthuis Aug 24 '11 at 20:44
  • 3
    @Rudy: I strongly disagree that "a good DLL won't let an exception escape." Do you expect every function in every DLL you load to surround the function call with a `__try/__except` block? What do you expect to do if somebody passes in a pointer into the stack's guard page? That would normally cause an exception that the OS will intercept, increase the stack size, and restart, but now if you're swallowing the exception, all of a sudden the code fails in mysterious ways. – Adam Rosenfield Aug 24 '11 at 21:10
  • @Adam: Yes, I do, if there is a chance an exception may occur. What do you mean with a "pointer into the stack's guard page"? Anyway, if the OS intercepts it, it will probably not propagate to the function. Once it reaches the function, it can't be caught by the OS anymore. – Rudy Velthuis Aug 24 '11 at 21:30
  • @Adam: OK, I read up on guard pages. They are a severe warning, that should be taken care of. The guard page can be used as if it were stack on the second and subsequent calls, but that is not really good behaviour, since you are still accessing beyond the stack. Anyway, they are a guard mechanism, not an "automatic extension of the stack" mechanism. One should not pass pointers outside the stack. That should be seen and treated as a stack overflow. – Rudy Velthuis Aug 24 '11 at 21:37
  • Rudy - you're simply wrong. Like Michael asked: "What should strcmp()" do if it's given a bad pointer?" Like Adam pointed out "if you're swallowing the exception, all of a sudden the code fails in mysterious ways". What exactly do you mean by "end gracefully"? Are you going to notify the program of the failure and give it a chance to recover? Stop the program altogether? Let the program carry on on blissful ignorance that anything's wrong? – paulsm4 Aug 24 '11 at 21:51
  • 1
    @paulsm4: Sorry, but no, I don't think I'm wrong. I maintain that a good DLL does not let exceptions escape. A good langage will be able to deal with DLLs that still do, but that doesn't take away what I say. You may think otherwise, but that does not make me wrong. I also said the function should end gracefully, that, among other things, means it should have a way to signal the error, e.g. a special return value, or something like GetLastError(). That is a matter of design. – Rudy Velthuis Aug 24 '11 at 21:58
  • 1
    @paulsm4: FWIW, letting exceptions escape is a matter of **bad** design, and is very likely to crash the caller, e.g. if that caller is not written in the same language or language version as the DLL. That will certainly not give the caller the opportunity to recover gracefully. – Rudy Velthuis Aug 24 '11 at 22:06
  • 1
    Crashing is better than failing silently. Period. The function in question (JdeStrcmp()) is ALREADY "signalling the error" ... but the guy who called it (SetCrossReferenceItemData(), in CSALES.DLL) is failing to detect the error. Should CSALES.DLL have better input validation? Yes, of course. Should CSALES.DLL have a try/catch (or Windows SEH try/catch)? Sure. Is JdeUnicode.dll "bad" because it let the exception "escape"? No. JdeUnicide and JdeStrcmp() are arguably doing EXACTLY THE RIGHT THING. – paulsm4 Aug 24 '11 at 22:29
  • 1
    @paulsm4: I never said the function should fail **silently**. I said it should fail gracefully, i.e. while not letting the exception escape the DLL. Of course an error should be signalled, somehow, to the caller. Windows API often uses a HResult or some other kind of error returns. Oh, and that is also final. PERIOD. Have you ever written DLLs that do let exceptions escape? If so, were your customers, especially those that do not use the same compiler, happy about it? – Rudy Velthuis Aug 24 '11 at 22:37
  • @paulsm4: The guy in CSALES.dll may not even have a way to **catch** the exception, or handle it. That depends on the language he uses, and on the fact his memory manager is not the same as the one in the DLL, so even if he can catch it, he might not be able to access it properly, i.e. derive meaning from it, or act upon it. -- Sure, he apparently passes invalid data. He should be told without letting his app crash, so he can actually try to recover gracefully. Bad data is not the only reason for an exception, after all. – Rudy Velthuis Aug 24 '11 at 22:48
  • 2
    Wow - stirred something up... (by the way, I +1'd because I think the core answer is fine). Note that as far as "exceptions escaping" a DLL, note that an invalid access isn't really a C++ exception (though the compiler can make it one). Passing it up isn't really a language issue - it's a platform issue (I won't speak to Delphi; I know nothing about it). See http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx for info on the stack guard page (it is an "automatic extension of the stack" mechanism on Windows) and what you should do with an invalid pointer ("You should crash"). – Michael Burr Aug 24 '11 at 23:30
  • Exactly, the compiler will make it one. And yes, you should perhaps crash here. There are many other possible exceptions that should not cause a crash, and it remains bad practice to let exceptions escape a module boundary, especially if your DLL is also supposed to be used in other languages. See the examples I gave. There are many more like them. – Rudy Velthuis Aug 24 '11 at 23:40
  • @paulsm4: You are wrong. I recommend you stay away from C++ before you hurt yourself. – Matt Joiner Aug 24 '11 at 23:55
  • 1
    The compiler *could* make it one - depends on the compiler options used. Anyway, it seems to me that if the caller gives you a bad pointer or a non-terminated string, you should just crash. In this case the exception is not the DLL's responsibility (even if it occurs in the DLL's code) - it's the caller's doing. And if you decide to 'handle' the access violation anyway, make sure you don't catch guard page exceptions, or the stack is screwed (and if there's a crash as a result it may be far from the cause, making it hard to troubleshoot). – Michael Burr Aug 25 '11 at 00:15
  • As I said: **an exception should never escape a DLL**. I have given a few examples of reasons and there are many more to be found when you google. **Don't let it happen, period**. That it is an extremely bad thing to do is not an opinion, it is a fact. -- That means that also when the DLL function is given bad data, no exception should leave the DLL. Of course the caller should be notified of the error. The error should not simply be swallowed. But it should **not** be passed on as an exception. There are other ways. – Rudy Velthuis Aug 25 '11 at 18:09
  • FWIW, guard page exceptions should be caught too. **They are after all guard pages, not some kind of automatic stack extension pages** and they are, after all, **exceptions**. One should not take those lightly. A guard page exception is a sign that something severe is wrong and indicates a stack overflow. That is when an app should crash, instead of happily and blindly going on using the now unlocked guard page. – Rudy Velthuis Aug 25 '11 at 18:15
  • @Rudy: You obviously do not understand how guard pages work, and you also seem to be confused about the difference between a language-level exception (in the C++/C#/Java sense) versus a Windows exception in the "structured exception handling") sense. Make sure you read thoroughly and completely understand [this blog post](http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx). A guard page is **not** a sign that something is severely wrong, and they are used all the time without your being aware of it. (continuing...) – Adam Rosenfield Aug 25 '11 at 18:40
  • Imagine this scenario. Your program starts up, with a couple of 4K pages for the stack, at the bottom of which is a guard page. You now call a function which allocates a small 256-byte buffer, pushing your stack into the guard page. You pass a pointer to that buffer into the function `strcpy` to copy a string into it. Since this is your first time accessing the guard page, it generates an access violation, which the default exception handler catches -- it notices that it's a guard page, extends the stack, sets up a new guard page, and restarts the instruction. (continuing...) – Adam Rosenfield Aug 25 '11 at 18:43
  • The pointer is now valid, and the string is copied into the new page. Everything is good. Now imagine if instead of that, `strcpy` checked if it had a valid pointer. It sees that it doesn't, and returns an error code or something. Oops, now your perfectly correct and functioning program now fails, but only when that function gets called when its near the guard page. But wait -- even if the program checks the error code, it now innocently stores a value in a local variable on the stack, and that causes an access violation. (continuing...) – Adam Rosenfield Aug 25 '11 at 18:45
  • 1
    The default exception handler doesn't do anything (it's not a guard page anymore), and your program crashes impossibly. Why? Because `strcpy` swallowed the guard page exception. Now replace `strcpy` with a function from your DLL (the function call crossing a DLL boundary doesn't change anything here), and you've got a program that crashes in impossible, hard-to-reproduce ways. That's why you should just crash when you're given an invalid pointer. Period. – Adam Rosenfield Aug 25 '11 at 18:47
  • ISTM that in systems that do use stack guard blocks, such an exception is handled **before** it percolates up to rudysStrCmp()'s try-except block anyway. I'll maintain that no exception should leave a DLL, no system exception and even less a language exception (which could result from a system exception too). – Rudy Velthuis Aug 25 '11 at 19:10
  • @RudyVelthuis let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2866/discussion-between-adam-rosenfield-and-rudy-velthuis) – Adam Rosenfield Aug 25 '11 at 19:27
0

Clearly you've got some "JD Edwards" application, which uses the .dll's jdeunicode.dll and jdekrnl.dll. The failure is located in function "JdeStrcmp()", in jdeunicode.dll.

JdeStrcmp() either:

a) has a bug

 ... or ...

b) fails to detect null or illegal arguments

SUGGESTIONS:

  • If your application uses JdeStrcmp() directly, make sure you check for null or illegal string arguments when you're comparing two strings. It would be useful to write test cases for different combinations of 8-bit ASCII and 16-bit Unicode strings while you're at it.

  • If you purchased this J.D. Edwards application and/or development library, contact their technical support. Perhaps they have an update you can install.

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • INFO: Entering kernel signal handler, process exiting soon: iParam: 1310990289 – CloudEagle Aug 24 '11 at 20:06
  • Thanks for your input. I cannot share the code as its an application code that's copyrighted. – CloudEagle Aug 24 '11 at 20:10
  • @user624128 - If the code that's calling JdeStrcmp() is your code, then fix it. Check the arguments being passed to this "Unicode-aware, J.D. Edwards String Compare" function before you call it. Otherwise, contact the vendor and have them fix it. – paulsm4 Aug 24 '11 at 21:22
  • 1
    PS: If anybody's the culprit here, it's "_SetCrossReferenceItemData()" in "CSALES.dll". He's the guy who's calling JdeStcmp() with bogus arguments. – paulsm4 Aug 24 '11 at 21:46