Angband Forums

Angband Forums (http://angband.oook.cz/forum/index.php)
-   Development (http://angband.oook.cz/forum/forumdisplay.php?f=10)
-   -   Solution for Angband crash on startup when compiled with Visual Studio (http://angband.oook.cz/forum/showthread.php?t=8873)

Gordon April 3, 2018 15:34

Solution for Angband crash on startup when compiled with Visual Studio
 
Symptoms:

Birth screens work fine, but Angband crashes with an access violation code 0xc0000005 in ntdll.dll just after displaying "Please wait..." in ui_leave_init().

Problem:

Shortly after calling ui_enter_world(), Term_xtra(TERM_XTRA_REACT, 0) is called which then calls init_graphics() in main-win.c This calls ReadDIB2_PNG() in readpng.c to read in the graphic tiles. The crash occurs when png_read_info(png_ptr, info_ptr) is called at line 102.

Solution:

libpng12.dll is multi-threaded and so requires Angband to be compiled with support for multi-threaded dlls. To do this you must set Use run-time library to Multithreaded DLL under Code Generation on the C/C++ tab in Project Settings. This causes the /MD flag to be set in the project Makefile.

Testing Environment:

Angband Version: 4.05
OS Version: Windows XP SP3
Visual Studio Version: 6.0 SP6

This very important detail should be added to angband_visual_studio_step_by_step.txt.

Gordon April 6, 2018 20:54

Well, it seems that this doesn't work with Visual Studio 2008. I found an alternate solution that seems to work in both Visual Studio 6.0 and Visual Studio 2008. This requires modification of readpng.c. At the beginning of the file, we need to add a function that forces libpng to use our runtime version of fread() instead of the one it was compiled with:

Code:


/**
 * Forces libpng to use the version of fread() from the run time library
 * that this program was compiled with.
 */
void ReadFileFunc(png_structp png_ptr, png_bytep data, png_size_t length) {
        FILE *file = (FILE *)png_get_io_ptr(png_ptr);
        fread(data, sizeof(png_byte), length, file);
}

/**
 * Imports a DIB from a PNG file. Once
 * the DIB is loaded, the function also creates a bitmap
 * and palette out of the DIB for a device-dependent form.
 *
 * Returns TRUE if the DIB is loaded and the bitmap/palette created, in which
 * case, the DIBINIT structure pointed to by pInfo is filled with the
 * appropriate handles, and FALSE if something went wrong.
 */
BOOL ReadDIB2_PNG(HWND hWnd, LPSTR lpFileName, DIBINIT *pInfo, DIBINIT *pMask, BOOL premultiply) {

Then in the body of ReadDIB2(), replace these lines:

Code:

        /* setup error handling for init */
        png_init_io(png_ptr, fp);
        png_set_sig_bytes(png_ptr, 8);
       
        png_read_info(png_ptr, info_ptr);

With these:

Code:

        /* setup error handling for init */
        png_set_read_fn(png_ptr, fp, ReadFileFunc);       
        png_set_sig_bytes(png_ptr, 8);
       
        png_read_info(png_ptr, info_ptr);

Testing Environment:

Angband Version: 4.0.5
OS Version: Windows XP SP3, Windows 7 SP1 64 bit
Visual Studio Version: 6.0 SP6, 2008 SP1


All times are GMT +1. The time now is 23:19.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.