Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (808)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (872)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1] 2
  ignore  |  Print  
  Byte buffer crashing  (Read 9167 times)
0 Members and 1 Guest are viewing this topic.
Offline CopyableCougar4
« Posted 2015-02-10 23:19:06 »

I have been trying to limit how often I post questions, but this one is just stumping me.

It only occurs after 24 bytes have been added (6 floats), and only to one of the three buffers.

I have a ByteBuffer where I send data to OpenGL with. No matter how I create the buffer, the JVM always crashes.

Portion of log:
1  
2  
3  
4  
5  
6  
7  
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  sun.misc.Unsafe.putInt(JI)V+0
j  java.nio.DirectByteBuffer.putFloat(JF)Ljava/nio/ByteBuffer;+33
j  java.nio.DirectByteBuffer.putFloat(F)Ljava/nio/ByteBuffer;+11
j  com.digiturtle.library.opengl.GLRenderer.addTriangle(Lcom/digiturtle/library/opengl/Renderer$Vertex;Lcom/digiturtle/library/opengl/Renderer$Vertex;Lcom/digiturtle/library/opengl/Renderer$Vertex;Lcom/digiturtle/library/opengl/GLTexture;)V+82
j  com.digiturtle.library.opengl.GLGlyph.render(Lcom/digiturtle/library/opengl/Renderer;Lcom/digiturtle/library/util/Color;Lcom/digiturtle/library/opengl/GLTexture;)V+303
j  com.digiturtle.library.opengl.GLString.render(Lcom/digiturtle/library/opengl/Renderer;)V+115


Here is how I have tried to create the buffer.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
// Method one
ByteBuffer buffer = ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
buffer.rewind();
return buffer;
// Method two
return ByteBuffer.allocate(size).order(ByteOrder.nativeOrder());
// Method three
return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
// Method four
return org.lwjgl.BufferUtils.createByteBuffer(size);


It was working two days ago, and no updates have happened since then, so I can't seem to find out what's wrong. I have googled a lot and have tried to find a solution, with no luck.

Thanks,
CopyableCougar4

Either wandering the forum or programming. Most likely the latter Smiley

Github: http://github.com/CopyableCougar4
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2015-02-10 23:23:37 »

Make a standalone compilable example and post it here. Method two and three cannot crash on Unsafe as they are not direct buffers.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline CopyableCougar4
« Reply #2 - Posted 2015-02-10 23:42:26 »

I couldn't reproduce it with just standalone example (which confuses me more and makes it harder to get community help).

However, I think I know why it's crashing after the first time. Every frame (based on some code from SHC that I added in the hopes of getting my renderer working) the buffer gets remapped with
glMapBuffer(target, access, pointer.capacity(), pointer);


I will try and do some debugging and see why the mapped buffer doesn't work the next time data is uploaded.

Either wandering the forum or programming. Most likely the latter Smiley

Github: http://github.com/CopyableCougar4
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #3 - Posted 2015-02-10 23:45:56 »

You are handed memory from the driver, you're not creating the ByteBuffer yourself, so those 'four methods that crash' are irrelevant. Besides, there are no valid use cases left for glMapBuffer - nobody should use it, switch to glMapBufferRange

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline CopyableCougar4
« Reply #4 - Posted 2015-02-10 23:54:42 »

Okay so I switched it to:

1  
2  
pointer = glMapBufferRange(target, offset, size, access, null);
// target is the buffer type, offset is passed as 0, size is in bytes (like it should be), access is GL_READ_WRITE


However, I still get crashes.

Either wandering the forum or programming. Most likely the latter Smiley

Github: http://github.com/CopyableCougar4
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #5 - Posted 2015-02-11 00:01:35 »

probably something silly like a missing
rewind()
and a funky pointer/position you let the float drop at. as long as it just crashes your VM Smiley .. try to find a position which destroys your OS graphic output, much more psychedelic fun.

what does toString() on the buffer say after you mapped it ?
Offline CopyableCougar4
« Reply #6 - Posted 2015-02-11 00:03:40 »

I added a rewind and it still crashes.

When I print the buffer's toString(), here's what is printed:
1  
java.nio.DirectByteBuffer[pos=0 lim=4194304 cap=4194304]

Either wandering the forum or programming. Most likely the latter Smiley

Github: http://github.com/CopyableCougar4
Offline CopyableCougar4
« Reply #7 - Posted 2015-02-11 00:08:14 »

After turning on the debug flag, it throws an exception because the address given is 0. However, I still can't wrap my mind around why the address is 0.

Either wandering the forum or programming. Most likely the latter Smiley

Github: http://github.com/CopyableCougar4
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #8 - Posted 2015-02-11 00:33:51 »

is the buffer already mapped when you map it .. maybe ? .. should generate a GL_INVALID_OPERATION tho'.

just for the sake .. here's one way to get the address of a bytebuffer (another faster is using unsafe) :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
public static class reflectiveAccessor
{
  private final static Field addressField;

  static
  {
    Field f = null;

    try
    {
      f = Buffer.class.getDeclaredField("address");
      if(!f.isAccessible()) f.setAccessible(true);
    }
    catch(final NoSuchFieldException e)
    {
      // deal with the error
    }

    addressField = f;
  }

  public static long getAddress(Buffer buffer)
  {
    try
    {
      return addressField.getLong(buffer);
    }
    catch(final IllegalAccessException e)
    {
       return -1;
    }
  }
}
in case you want to double check.
Offline CopyableCougar4
« Reply #9 - Posted 2015-02-11 00:39:47 »

I do
1  
glUnmapBuffer(target);
after I upload all the data.

Also, I have some code that throws a runtime exception every frame if GL11.glGetError() isn't 0, so there isn't an error there.

Either wandering the forum or programming. Most likely the latter Smiley

Github: http://github.com/CopyableCougar4
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #10 - Posted 2015-02-11 00:42:50 »

then i'm as clueless as you Wink
Offline CopyableCougar4
« Reply #11 - Posted 2015-02-11 00:49:46 »

So I have the issue traced back to native code.

1  
nglMapBufferRange(target, offset, length, access);


The above method, when invoked, returns 0. I set target to GL_ARRAY_BUFFER, offset to 0, length to the buffer size in bytes, and access to GL_READ_WRITE.

Either wandering the forum or programming. Most likely the latter Smiley

Github: http://github.com/CopyableCougar4
Offline SHC
« Reply #12 - Posted 2015-02-11 08:42:27 »

I think it might be with accesses, I first map the buffer before calling glDrawArrays with GL_ARRAY_BUFFER, 0, buffer.capacity() and GL_WRITE_ONLY. I unmap the buffers right after rendering. I don't get why it is not working.

Offline superminer362

Senior Newbie


Medals: 3
Exp: 1 year



« Reply #13 - Posted 2015-02-11 09:15:02 »

According to the OpenGL specification,
glMapBufferRange
takes a bitfield of access flags, so the equivalent of
GL_READ_WRITE
is
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT
. Hope this helps.
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #14 - Posted 2015-02-11 10:35:50 »

Are you using LWJGL 2 or 3?

Spasi: IIRC LWJGL 2
glMapBuffer[Range]
returned
null
instead of a ByteBuffer pointing to 0L

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline CopyableCougar4
« Reply #15 - Posted 2015-02-11 11:06:50 »

I'm using LWJGL 3.

Either wandering the forum or programming. Most likely the latter Smiley

Github: http://github.com/CopyableCougar4
Offline Spasi
« Reply #16 - Posted 2015-02-11 11:33:40 »

LWJGL 3 indeed by default returns a ByteBuffer pointing at 0L. If you enable debug mode (-Dorg.lwjgl.util.Debug=true) you will get an exception instead.

You could argue that it's a problem with LWJGL, but this is an application bug really. You're using the result of MapBuffer without checking for OpenGL errors. Which I'm sure what is happening here, otherwise you wouldn't be getting a null pointer back.

I highly recommend setting up a debug message callback while developing your application. It's particularly easy in LWJGL 3:

1  
debugProc = GLContext.createFromCurrent().setupDebugMessageCallback();

Don't forget to store the returned Closure somewhere, like GLFW callbacks. You may also have to create a debug context (see the GLFW_OPENGL_DEBUG_CONTEXT window hint).
Offline theagentd
« Reply #17 - Posted 2015-02-11 11:45:04 »

Checking for errors using glGetError() can ruin performance since it causes a driver thread sync. Since there is no way (?) to figure out the address of the returned buffer, I'd strongly prefer it returning null. That makes it much clearer what's going on.

Myomyomyo.
Offline KaiHH

JGO Kernel


Medals: 820



« Reply #18 - Posted 2015-02-11 12:02:41 »

Checking for errors using glGetError() can ruin performance...
Sorry for saying that, but saying this right after spasi pointed out to check for a GL error, is just stupid.

As long as there is evidence of your code having a programming error in it, you should not give a damn about performance at all, but instead should focus on getting rid of the source of the error. Therefore you most certainly want to insert an error check after each and every single GL call...
Offline theagentd
« Reply #19 - Posted 2015-02-11 12:11:30 »

Checking for errors using glGetError() can ruin performance...
Sorry for saying that, but saying this right after spasi pointed out to check for a GL error, is just stupid.

As long as there is evidence of your code having a programming error in it, you should not give a damn about performance at all, but instead should focus on getting rid of the source of the error. Therefore you most certainly want to insert an error check after each and every single GL call...

If I wanted my program to crash without a decent stack trace in a way that's hard to debug I wouldn't use Java in the first place. I can check for null every time I map a buffer, but having to call glGetError() if debug callbacks aren't supported is a nightmare.

Myomyomyo.
Offline KaiHH

JGO Kernel


Medals: 820



« Reply #20 - Posted 2015-02-11 12:15:56 »

Yes, but Java makes no difference here, really. In native code you would of course also rely on glGetError().
Java cannot help you there since the action mostly happens in the driver's native code anyway.
Offline Spasi
« Reply #21 - Posted 2015-02-11 12:17:38 »

I'm open to returning null, but not because glGetError is "expensive". If the default behavior confuses users or makes debugging harder, then it obviously has to change.

Btw, I never said use glGetError, or fill your code with error checks. There is a reason LWJGL 3 does not have a "debug jar" like LWJGL 2, manual checking is obsolete now that we have the *_debug_output extensions and OpenGL 4.3+. Note that the error checking itself is not (more) expensive, the driver has to do it in any case, it's reporting the error that causes performance problems. This issue goes away with debug output, because the debug callbacks may be called asynchronously (i.e. not in the same thread that called the OpenGL function and triggered an error) and you also have full control of the level of error/issue reporting.
Offline KaiHH

JGO Kernel


Medals: 820



« Reply #22 - Posted 2015-02-11 12:24:53 »

[...] manual checking is obsolete now that we have the *_debug_output extensions and OpenGL 4.3+.
What's with drivers that do not expose that debug output extension?

[...] This issue goes away with debug output, because the debug callbacks may be called asynchronously (i.e. not in the same thread that called the OpenGL function and triggered an error) and you also have full control of the level of error/issue reporting.
Because of this asynchronicity is it then not possible for your program to crash because of a faulty GL call before being able to receive a GL error asynchornously by the driver in time?
Offline Spasi
« Reply #23 - Posted 2015-02-11 12:29:27 »

What's with drivers that do not expose that debug output extension?

Are there such drivers? Note, this is for development only, the deployed application does not have to require a debug output extension.

Because of this asynchronicity is it then not possible for your program to crash because of a faulty GL call before being able to receive a GL error asynchornously by the driver in time?

If that indeed happens, you can enable GL_DEBUG_OUTPUT_SYNCHRONOUS.
Offline KaiHH

JGO Kernel


Medals: 820



« Reply #24 - Posted 2015-02-11 12:32:03 »

If that indeed happens, you can enable GL_DEBUG_OUTPUT_SYNCHRONOUS.
Oh that's neat! Smiley
Just wanted to rule out all possible eventualities that can let me shoot myself in the foot.
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #25 - Posted 2015-02-11 13:08:23 »

I'm open to returning null, but not because glGetError is "expensive". If the default behavior confuses users or makes debugging harder, then it obviously has to change.
Returning null gets my vote, as in the Java ecosystem, a ByteBuffer instance ought to be trusted (at least between glMapBuffer and glUnmapBuffer).

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #26 - Posted 2015-02-11 13:16:14 »

if you ask me, i vote for not returning any bytebuffer, just the long address would be make me happy.
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #27 - Posted 2015-02-11 13:36:22 »

if you ask me, i vote for not returning any bytebuffer, just the long address would be make me happy.

basil_: that's the difference between glMapBuffer and nglMapBuffer

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #28 - Posted 2015-02-11 15:20:55 »

oh, that's new in 3.x ?

correct me but with 2.9.x ngl methods are not really available and even if, native methods already return a bytebuffer .. right ? or am i blind again ?
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #29 - Posted 2015-02-11 15:41:45 »

basil_: this is the new 'layered' API design in LWJGL 3

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Pages: [1] 2
  ignore  |  Print  
 
 

 
mercenarius (6 views)
2020-06-04 19:26:01

mercenarius (5 views)
2020-06-04 19:13:43

Riven (850 views)
2019-09-04 15:33:17

hadezbladez (5834 views)
2018-11-16 13:46:03

hadezbladez (2636 views)
2018-11-16 13:41:33

hadezbladez (6251 views)
2018-11-16 13:35:35

hadezbladez (1504 views)
2018-11-16 13:32:03

EgonOlsen (4740 views)
2018-06-10 19:43:48

EgonOlsen (5798 views)
2018-06-10 19:43:44

EgonOlsen (3282 views)
2018-06-10 19:43:20
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!