How to debug the C code when running inside Java using JNA

18 views
Skip to first unread message

Support

unread,
Sep 29, 2024, 2:54:08 AM9/29/24
to jna-users
Greetings team and compliments of the day.

I am stuck: a generally working C PNG encoder segfaults for a particular file and I have no idea why. The C code is below, the MALLOC fails with message:

malloc(): corrupted top size

Now I would love to know what exactly I try to maloc for my example so I inserted some printfs. But nothing is printed out and I have not idea why?
What would be the best way (except GDB) to see what's going on in the C code when running inside Java with JNA please?

Thanks already for helping and cheers!
Andreas

EXPORT ByteArray* fpng_encode_image_to_memory(const void* pImage, uint32_t w, uint32_t h, uint32_t num_chans,  uint32_t flags = 0) {
// Vector frees itself
std::vector<uint8_t> out_buf;

printf("Program started...\n"); // Check if the program starts correctly
fflush(stdout); // Ensure output is flushed

if (num_chans==(uint32_t) 4) {
swapChannelsABGRtoRGBA( (unsigned char*) pImage, w * h);
} else {
swapChannelsBGRtoRGB( (unsigned char*) pImage, w * h);
}

bool result = fpng::fpng_encode_image_to_memory( pImage, w, h, num_chans, out_buf, flags);

printf("Size of out_buf: %zu\n", out_buf.size());
fflush(stdout);

ByteArray* data = (ByteArray*) malloc( sizeof(ByteArray) );
data->size = out_buf.size();
data->data = (uint8_t*) malloc( out_buf.size() * sizeof(uint8_t) );

// copy the uint8_t* array
std::memcpy(data->data, out_buf.data(), out_buf.size());

return data;
}

Matthias Bläsing

unread,
Sep 29, 2024, 8:50:24 AM9/29/24
to jna-...@googlegroups.com

Hi Andreas,

> I am stuck: a generally working C PNG encoder segfaults for a particular file and I have no idea why. The C code is below, the MALLOC fails with message:
>
> malloc(): corrupted top size

most probable problem: Your bindings are wrong. If you screw up the
signature, you'll get wrong stack setup and that might crash with the
heap.

> Now I would love to know what exactly I try to maloc for my example so I inserted some printfs. But nothing is printed out and I have not idea why?

Most probably, because the code you modify is not the code you build. I
used the "just printf what you want to know"-method in the past with
JNA and it worked.

You might want to check how you call your programm, as the environment
might redirect stdout. I faced this problem in combination with junit
tests and had to change the build script to pass through the output.
>
> EXPORT ByteArray* fpng_encode_image_to_memory(const void* pImage, uint32_t w, uint32_t h, uint32_t num_chans, uint32_t flags = 0)

The last argument looks broken. C (to my knowledge) does not allow
overloaded calls and even if it would allow them, it would raise the
question how they are realized.

In the end JNA/libffi setup the stack and jump to the function, for
this they need to know how the stack has to look before jumping and
they have to know where. If the name is not unique, I don't see how
this should work.

Greetings

Matthias

Support

unread,
Sep 29, 2024, 9:40:20 AM9/29/24
to jna-...@googlegroups.com
Thank you so much for helping, Matthias!

On Sun, 2024-09-29 at 14:50 +0200, 'Matthias Bläsing' via Java Native Access wrote:


I am stuck: a generally working C PNG encoder segfaults for a particular file and I have no idea why. The C code is below, the MALLOC fails with message:

malloc(): corrupted top size

most probable problem: Your bindings are wrong. If you screw up the
signature, you'll get wrong stack setup and that might crash with the
heap.

We can rule this one out as the program works for all kind of Java BufferedImages with 3 or 4 channels -- except this one picture, which works only with 3 channels but fails with 4.


Now I would love to know what exactly I try to maloc for my example so I inserted some printfs. But nothing is printed out and I have not idea why?

Most probably, because the code you modify is not the code you build. I
used the "just printf what you want to know"-method in the past with
JNA and it worked.

Ok, I will double check this. I had a similar suspicion.
I will disable MAVEN und JUNIT tests and go low level.


You might want to check how you call your programm, as the environment
might redirect stdout. I faced this problem in combination with junit
tests and had to change the build script to pass through the output.

EXPORT ByteArray* fpng_encode_image_to_memory(const void* pImage, uint32_t w, uint32_t h, uint32_t num_chans,  uint32_t flags = 0)

The last argument looks broken. C (to my knowledge) does not allow
overloaded calls and even if it would allow them, it would raise the
question how they are realized.

Again, it works in general. Just not with this one file and 4 channels.
I think I need to get the printf output working first to see what is really going on. I am sure we will laugh about it once we find out.

thanks again for helping!
Cheers
Andreas

L Will Ahonen

unread,
Sep 29, 2024, 1:59:58 PM9/29/24
to Java Native Access
Hi,

The java part looks simple enough for reimplementing in C - to make sure the encoder library does not crash when fed that particular file.

Signed,
Someone Who Wrestled With JNA Only To Realize The Underlying Library Was Broken

Support

unread,
Sep 29, 2024, 8:24:02 PM9/29/24
to jna-...@googlegroups.com
Dear All,

thank you a lot for helping! As promised, we will laugh eventually:

There were a few issues with my code (and I was too tired yesterday, to think it through methodically). Be set for a good laugh:

1) it really confused me that the error was MALLOC related (a java programmer gets always an exception with a line number and so he is easily lost with C error behaviour)

2) that's why I did not see into the Byte Swap methods before which had a very simple buffer overflow when files are short

3) now the most ridiculous part: Since I need to carry the C code wrapped in the Java library and unwrap it, I implemented a caching mechanism and forgot about it. So whenever I ran my tests and tried to debug, this cache was touched and never the actual work. Funny me.

Apologies for wasting your time, thank you much for your help and cheers!
Andreas

PS: I am updating everything as we speak. Check out https://github.com/manticore-projects/fpng-java if you need the fastest possible SSE/AVX PNG encoders in Java.
Reply all
Reply to author
Forward
0 new messages