skiselkov / libacfutils

58 stars 19 forks source link

Crash when loading shader and __imp____iob_func #5

Open xDennis0811 opened 5 years ago

xDennis0811 commented 5 years ago

Hey, I built the dependencies and then build a redist version for Linux with Ubuntu 18.04.After that I put my include directory from acfutils in my include direction for my project and add the libs folder to my library search paths in Visual Studio 2019.When I try to load shaders, xplane just crashes with an abort().I initialized GLEW with glewInit() and after that I tried to load shaders from text with shader_prog_from_text_v(const char *progname, const char *vert_text, const char *frag_text, const shader_attr_bind_t *binds) but then xp just crashes.Another thing is that when I try to use the log class, visual studio throws the error unresolved external symbol __imp____iob_func for the log_backtrace function.Are their any known solutions for my problems ? :)

skiselkov commented 5 years ago

The library requires some boilerplate to get initialized:

  1. Whenever the library needs to log something, it needs a way to know how to do that. So the first thing you should always do is provide a logging function via the log_init function:
    
    /* This will be your custom logging function */
    static void my_dbg_logger(const char *str)
    {
    XPLMDebugString(str);
    }

PLUGIN_API int XPluginStart(char name, char sig, char desc) { ... /

PLUGIN_API void XPluginStop(void) { ... / No more libacfutils calls after this! / log_fini(); }



2. That issue with ``__imp____iob_func`` is because VS2015 changed how Microsoft exposes certain stdio pointer definitions (and MinGW still uses the older method). To get this going, you need a bit of glue code in your plugin build on VS. I have provided the glue code in the library here: https://github.com/skiselkov/libacfutils/blob/master/msvc_compat/lacf_msvc_compat.cpp
You will want to include this file in your project to be built into the resulting binary.

3. libacfutils uses a special multi-threaded mod of GLEW (GLEW-MX), which is a bit more complicated to set up on Windows. On Linux & Mac, just calling ``glewInit`` is enough. However, on Windows you will also want to add some ``DllMain`` hooks. The above msvc compat file already contains the necessary code. However, if you already have a ``DllMain`` function in your plugin, you will want to disable that functionality from the compat file. To do so, define the ``_LACF_DISABLE_DLLMAIN`` macro and make sure you replicate the contents of the ``lacf_glew_dllmain_hook`` function inside of your ``DllMain`` (you basically need to call a couple of libacfutils functions on certain events): https://github.com/skiselkov/libacfutils/blob/master/src/glew.c#L46-L60
xDennis0811 commented 5 years ago

Hey thanks for your answer :) I did it with the logging function but I just did it with log_init(XPLMDebugString, „my_logger“).I just added the file in visual studio via Add Exisiting Item to my source folder.And I forgot to include the dllMain maybe that’s the reason why it doesn’t work but I’ll try that later, thank you :) EDIT: I just took the hello world example for sdk version 3 and added the include folders to my include path and added the libs folder with all the .a files to my libs search path, if that helps and I’m using Windows 10 64Bit with Visual Studio 2019 :)

xDennis0811 commented 5 years ago

Okay the log problem is fixed but the crash when loading a shader is still there.I put this into my main class: ` bool inited = false;

BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID resvd) { if (inited == false) { XPLMDebugString("DLL MAIN \n"); lacf_glew_dllmain_hook(reason); inited = true; } return (TRUE); } and use inited because the DllMain was called twice before.When I now do this: log_init(my_dbg_logger, "test_plugin"); logMsg("PLUGIN INIT"); / If you want to use the crc64-based fast PRNG, initialize it too / crc64_init(); crc64_srand(time(NULL));

GLenum err;
err = glewInit();
if (err != GLEW_OK) {
    logMsg("FATAL ERROR: cannot initialize libGLEW: %s",
        glewGetErrorString(err));
    return (B_FALSE);
}
logMsg("SUPPORTED OPENGL VERSION: %s", glGetString(GL_VERSION));

shader_prog_from_text("test_prog", "", "");

x-plane just crashes on startup with the log: DLL MAIN 2019-07-03 15:04:47 test_plugin[Hello-World-SDK-3.cpp:59]: PLUGIN INIT 2019-07-03 15:04:47 test_plugin[Hello-World-SDK-3.cpp:71]: SUPPORTED OPENGL VERSION: 4.6.0 NVIDIA 419.67 --=={This application has crashed because of the plugin: Test/64/win.xpl}==-- ` So there must be still an error somewhere and oh yes I just removed the DllMain-part from the lacf_msvc_combat.cpp.

xDennis0811 commented 5 years ago

Okay I downloaded it again and build the dependencies via build_deps file and then build the redist version with build_redist file.After that I included the include directory and the libs folder.I used this code: ` log_init(XPLMDebugString, "my_logger"); logMsg("LOGGER INITED: %s", "v1.0");

GLenum err = glewInit();
if (GLEW_OK != err)
{
    logMsg("GLEW INIT FAILED WITH CODE: %s\n", glewGetErrorString(err));
}
logMsg("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));

GLint new_prog;

new_prog = shader_prog_from_file("test_prog", "C:/Users/Dennis/Desktop/Hello-World-SDK-3/vertex.vs", "C:/Users/Dennis/Desktop/Hello-World-SDK-3/fragment.fs");
logMsg("SHADER ID: %i", new_prog);

` And x-plane crashed all the time when I try to load a shader which is really weird.Any suggestions ?

EDIT: I found this in my log file now 2019-07-04 15:47:05 my_logger[glew.c:65]: assertion lacf_glew_ctx_key == 0 failed (0x43 == 0x0)

EDIT2: The assertion error is only in the log if I force to call dll_main_hook with the reason of THREAD_ATTACH and PROCESS_ATTACH otherwise nothing appears

skiselkov commented 5 years ago

Thinking. However, you CAN'T force a manual call to lacf_glew_dllmain_hook. The assertion you are seeing is due to a duplicate call to lacf_glew_dllmain_hook.

xDennis0811 commented 5 years ago

Okay that’s really weird.If I just copy the content of the dllMain from the other class shader loading just doesn’t work and I can’t get shader loading working because that’s the only thing I need to get working.I think I compiled everything after the instructions but what can be the problem ? :)

xDennis0811 commented 5 years ago

Okay I downloaded your latest pre-release with the already build static libraries.I started up Visual Studio 2019, included the include directory and the win64/include directory and for the libs I included the win64/lib directory.Then I used this code for my main class:

include` "XPLMDisplay.h"

include "XPLMGraphics.h"

include "XPLMUtilities.h"

include <acfutils/log.h>

include <acfutils/glew.h>

include <acfutils/shader.h>

include

PLUGIN_API int XPluginStart(char outName,char outSig,char * outDesc) { strcpy(outName, "HelloWorld3Plugin"); strcpy(outSig, "xpsdk.examples.helloworld3plugin"); strcpy(outDesc, "A Hello World plug-in for the XPLM300 SDK.");

logMsg("LOGGER INITED: %s", "v1.0");

GLenum err = glewInit();
if (GLEW_OK != err)
{
    logMsg("GLEW INIT FAILED WITH CODE: %s\n", glewGetErrorString(err));
}
logMsg("Status: Using GLEW %s", glewGetString(GLEW_VERSION));
logMsg("Using OpenGL Version: %s", glGetString(GL_VERSION));

GLint new_prog;

new_prog = shader_prog_from_file("test_prog", "C:/Users/Dennis/Desktop/Hello-World-SDK-3/vertex.vs", "C:/Users/Dennis/Desktop/Hello-World-SDK-3/fragment.fs");

return 1;

}

PLUGIN_API void XPluginStop(void) { }

PLUGIN_API void XPluginDisable(void) { } PLUGIN_API int XPluginEnable(void) { return 1; } PLUGIN_API void XPluginReceiveMessage(XPLMPluginID inFrom, int inMsg, void * inParam) { }

and this Code for the lacf_msvc_compat.cpp file:

include

include

include "XPLMUtilities.h"

include

include <acfutils/glew.h>

FILE _iob[] = { stdin, stdout, *stderr };

extern "C" FILE *cdecl iob_func(void) { return (_iob); }

char* printReason(DWORD reason) { switch (reason) { case DLL_PROCESS_DETACH: return "DLL PROCESS DETACH"; break; case DLL_PROCESS_ATTACH: return "DLL PROCESS ATTACH"; break; case DLL_THREAD_ATTACH: return "DLL THREAD ATTACH"; break; case DLL_THREAD_DETACH: return "DLL THREAD DETACH"; break; } }

/*

BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID resvd) { log_init(XPLMDebugString, "my_logger"); logMsg("Reason: %s", printReason(reason));

lacf_glew_dllmain_hook(reason);

return (TRUE);

}

endif / _LACF_DISABLE_DLLMAIN /

For some reason the process get detached twice shortly after the init code is finished.Here is my log: 2019-07-06 15:33:21 my_logger[lacf_msvc_compat.cpp:64]: Reason: DLL PROCESS ATTACH 2019-07-06 15:33:21 my_logger[Hello-World-SDK-3.cpp:21]: LOGGER INITED: v1.0 2019-07-06 15:33:21 my_logger[Hello-World-SDK-3.cpp:28]: Status: Using GLEW 1.13.0 2019-07-06 15:33:21 my_logger[Hello-World-SDK-3.cpp:29]: Using OpenGL Version: 4.6.0 NVIDIA 419.67 2019-07-06 15:33:21 my_logger[lacf_msvc_compat.cpp:64]: Reason: DLL THREAD DETACH 2019-07-06 15:33:21 my_logger[lacf_msvc_compat.cpp:64]: Reason: DLL THREAD DETACH --=={This application has crashed because of the plugin: Test/64/win.xpl}==--

vertex.vs: `

version 460

layout (location = 0) in vec3 aPos;

out vec4 vertexColor;

void main() { gl_Position = vec4(aPos, 1.0); vertexColor = vec4(0.5, 0.0, 0.0, 1.0); } `

fragments.fs: `

version 460

out vec4 FragColor;

in vec4 vertexColor; // the input variable from the vertex shader (same name and same type)

void main() { FragColor = vertexColor; } `

xDennis0811 commented 5 years ago

Do you maybe have now a solution for the problem ? Because I really need the glew part from your Library :)