Win a copy of Microservices in Action this week in the Web Services forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
  • Campbell Ritchie
  • Bear Bibeault
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Knute Snortum
  • Junilu Lacar
  • paul wheaton
Saloon Keepers:
  • Ganesh Patekar
  • Frits Walraven
  • Tim Moores
  • Ron McLeod
  • Carey Brown
  • Stephan van Hulst
  • salvin francis
  • Tim Holloway

EXCEPTION_ACCESS_VIOLATION (0xc0000005) When Accessing a Buffer with JNI.  RSS feed

Posts: 1464
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham posted a good cautionary tale in the synchronization forum. I hope this one in this forum is as useful to someone, somewhere.

In my C++ native method, I had this code:

The call from Java looked like this:

In effect, the Java side passed an array of integers to a native method, that, in turn, processed it as an array of bytes, returning it as an array of integers.

Later, I had to change the Java side so it actually used BufferedImages made up of bytes, not integers, so the code looked like this:

This also ran. But, it also crashed, and did so both erratically and enigmatically, with an error message something like this:

# An unexpected error has been detected by Java Runtime Environment:
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d830c3b, pid=2352, tid=2404

The problem turned out to be in Line 7 (and, in a way, also Line 11) of my native method. I was still using GetIntArrayElements() when I should have been using GetByteArrayElements(). C++, of course, is very relaxed about casting pointers from one type to another, so I was able to pass what had been a pointer to an array of integers to something expecting a pointer to an array of bytes, and make it work (indeed, a lot of perfectly good C/C++ code relies on the ability to treat integers as bytes in just this way). So, when GetIntArrayElements() continued to return a pointer to a memory buffer, it never occurred to me that there was anything wrong. But there was: the GetIntArrayElements() and GetByteArrayElements() methods either pin down the original array, or else copy it. Either way, they need to be able to copy back your data if your changes are going to show up on the Java side when your native method returns. Apparently, either method called on a jbyteArray will return a valid C++ pointer to its memory, but only GetByteArrayElements() correctly manages the business of returning your data. Calling GetIntArrayElements() gives you a valid pointer, but it doesn't protect the original object in the same way GetByteArrayElements() does, allowing the error above to come up from time to time.

What made this hard to discover was that both methods do return a valid pointer, not an error code. That's somewhat surprising, but maybe that was a design decision made in favor of efficiency over type safety. Or, maybe checking the type of the array passed to those methods is harder than I think it is. Regardless, it was an annoying bug, and hard to Google (since that error message can have any number of causes, most of which have little to do with what I was doing wrong).

I get a lot of good help here. Maybe this will be of benefit to someone else.
Ranch Hand
Posts: 69
C++ Linux Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

C++, of course, is very relaxed about casting pointers from one type to another

Just want to point out that this is false. What your code depicts is a C-style cast, which is a legacy artifact from C. Static pointer casting in C++ is completely type-safe when the language is not abused by c-style and reinterpret_casting used in improper contexts, though JNI is a C interface and not a C++ interface. Another reason to use extra caution when blending C and C++
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!