Bug 702910 - Can't build THREADSAFE Ghostscript Release DLL with Visual Studio
Summary: Can't build THREADSAFE Ghostscript Release DLL with Visual Studio
Status: RESOLVED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: Build Process (show other bugs)
Version: 9.53.0
Hardware: PC Windows 10
: P4 normal
Assignee: Chris Liddell (chrisl)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-09-16 09:19 UTC by Dave Miller
Modified: 2021-02-15 14:57 UTC (History)
1 user (show)

See Also:
Customer:
Word Size: ---


Attachments
Patch (2.13 KB, patch)
2020-09-19 20:21 UTC, Peter Cherepanov
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dave Miller 2020-09-16 09:19:05 UTC
Hi,

As we try to build Ghostscript (checked with 9.53.0 and 9.52 versions) with THREADSAFE parameter, using Visual Studio 2019 over Windows 10, build process returns an error:

Error LNK2019 unresolved external symbol errprintf_nomem referenced in function gs_log_error

Error is located in mkromfs.c file, which has a method called errprintf_nomem that can't be found when GS_TRHEADSAFE is set.

To give some context:

We see from doc\History9.htm: 

------------------------------------
2019-05-29 15:56:20 -0700  
Ray Johnston <ray.johnston@artifex.com>
{650c49424529fca922519ee9cdf2086eee5cfb70} 
Fix broken DEBUG build. Add standalone gs_log_error to mkromfs.c

This function is invoked for DEBUG builds by gs_note_error. We define
an equivalent local version so we don't have to include gsmisc.obj
(as for other utility functions such as outprintf).

base/mkromfs.c

------------------------------------

So, taking a look at mkromfs.c file (were exception raises on compiling):

int
gs_log_error(int err, const char *file, int line)
{
    if (file == NULL)
        errprintf_nomem("Returning error %d.\n", err);
    else
        errprintf_nomem("%s(%d): Returning error %d.\n",
                 (const char *)file, line, err);
    return err;
}

It always calls to errprintf_nomem function. Looking for its definition on same file:

#ifndef GS_THREADSAFE
int errprintf_nomem(const char *fmt, ...)
{
    int count;
    char buf[PRINTF_BUF_LENGTH];
    va_list args;

    va_start(args, fmt);
    count = vsnprintf(buf, sizeof(buf), fmt, args);
    if (count < 0 || count >= sizeof(buf))  { /* MSVC || C99 */
        fwrite(buf, 1, sizeof(buf) - 1, stderr);
        fwrite(msg_truncated, 1, sizeof(msg_truncated) - 1, stderr);
    } else {
        fwrite(buf, 1, count, stderr);
    }
    va_end(args);
    return count;
}
#endif

So, errprintf_nomem won't be present when compiling using GS_THREADSAFE flag, even it is referenced by gs_log_error which was introduced as standalone function on 2019-05-29, as referenced on History9.htm file.

I guess there should be an alternative definition for the local defined gs_log_error in case GS_THREADSAFE is present.

Note: To compile with THREADSAFE  capability, we simple use this sentence on "Rebuild all" option:
cd .. && nmake -f psi\msvc32.mak WIN64= SBR=1 DEVSTUDIO= XCFLAGS=-DGS_THREADSAFE=1 && nmake -f psi\msvc32.mak WIN64= DEVSTUDIO= XCFLAGS=-DGS_THREADSAFE=1 bsc

Thanks in advace.
Comment 1 Peter Cherepanov 2020-09-19 20:21:31 UTC
Created attachment 19841 [details]
Patch

There are several ways to fix this:
Since local versions of errprintf_nomem() and  errprintf() are mostly identical,
one can just call errprintf() with a dummy mem argument. This approach is implemented in the attached patch.

One can also keep errprintf_nomem() in all cases, because mkromfs does not need thread safety, and the local version of errprintf_nomem() is thread safe anyway.

It is also possible to use call fprintf(stderr, ...) directly in mkromfs and reduce the level of indirection and confusion even more.
Comment 2 Ray Johnston 2020-09-22 21:39:28 UTC
Sorry, Chris.

BTW, I can force this same error on linux (so Chris doesn't have to mess with
linux) using:

 make  XCFLAGSAUX=-DGS_THREADSAFE
Comment 3 Chris Liddell (chrisl) 2021-02-15 14:57:20 UTC
Slightly tweaked patch applied in:

https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=0ca4ae94020a

Thanks