[Bug 50556] New: Wine-Gecko debug channel 'gecko' doesn't work (win32 API 'SetEnvironmentVariable' has no effect on CRT 'getenv')

WineHQ Bugzilla wine-bugs at winehq.org
Sun Jan 24 14:11:43 CST 2021


https://bugs.winehq.org/show_bug.cgi?id=50556

            Bug ID: 50556
           Summary: Wine-Gecko debug channel 'gecko' doesn't work (win32
                    API 'SetEnvironmentVariable' has no effect on CRT
                    'getenv')
           Product: Wine
           Version: 6.0
          Hardware: x86-64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: mshtml
          Assignee: wine-bugs at winehq.org
          Reporter: focht at gmx.net
      Distribution: ---

Hello folks,

found by chance while checking some issues with Wine-Gecko. Many years ago one
had to manually set/export 'NSPR_LOG_MODULES=all:5' environment variable to get
more verbosity from Gecko engine.

Since commit
https://source.winehq.org/git/wine.git/commitdiff/f9cbbab53b27ab5b9801d56359e660be671626c9
("mshtml: Added gecko debug channel to control Gecko logging."), part of Wine
1.1.12 release, this wasn't necessary anymore.

After that, 'WINEDEBUG=+gecko' achieves the same.

Wine source:

https://source.winehq.org/git/wine.git/blob/2d4dd4252b0cf6526b3cc8194cce642b16eb12f6:/dlls/mshtml/nsembed.c#l443

--- snip ---
 443 static void set_environment(LPCWSTR gre_path)
 444 {
 445     size_t len, gre_path_len;
 446     int debug_level = 0;
 447     WCHAR *path, buf[20];
 448     const WCHAR *ptr;
 449 
 450     SetEnvironmentVariableW(L"XPCOM_DEBUG_BREAK", L"warn");
 451 
 452     if(TRACE_ON(gecko))
 453         debug_level = 5;
 454     else if(WARN_ON(gecko))
 455         debug_level = 2;
 456     else if(ERR_ON(gecko))
 457         debug_level = 1;
 458 
 459     swprintf(buf, ARRAY_SIZE(buf), L"all:%d", debug_level);
 460     SetEnvironmentVariableW(L"NSPR_LOG_MODULES", buf);
 461 
 462     len = GetEnvironmentVariableW(L"PATH", NULL, 0);
 463     gre_path_len = lstrlenW(gre_path);
 464     path = heap_alloc((len+gre_path_len+1)*sizeof(WCHAR));
 465     if(!path)
 466         return;
 467     GetEnvironmentVariableW(L"PATH", path, len);
 468 
 469     /* We have to modify PATH as xul.dll loads other DLLs from this
directory. */
 470     if(!(ptr = wcsstr(path, gre_path))
 471        || (ptr > path && *(ptr-1) != ';')
 472        || (ptr[gre_path_len] && ptr[gre_path_len] != ';')) {
 473         if(len)
 474             path[len-1] = ';';
 475         lstrcpyW(path+len, gre_path);
 476         SetEnvironmentVariableW(L"PATH", path);
 477     }
 478     heap_free(path);
 479 }
--- snip ---

It worked until Wine-Gecko was built with msvcrt/UCRT runtime.

Wine-Gecko 2.47.1, part of Wine 5.0-rc1 release.

https://source.winehq.org/git/wine.git/commitdiff/5f0b5d350566a46f0f999e4cff7ad9e280fcfa05
("mshtml: Update to Wine Gecko 2.47.1.")

--- snip ---
$ WINEDEBUG=+relay,+gecko wine iexplore.exe 
...
031c:Call KERNEL32.SetEnvironmentVariableW(01836084
L"NSPR_LOG_MODULES",0031cfb0 L"all:5") ret=017c2ea1
...
031c:Ret  KERNEL32.SetEnvironmentVariableW() retval=00000001 ret=017c2ea1 
...
031c:Call ucrtbase.getenv(0b5d46b0 "NSPR_LOG_MODULES") ret=0b58b3f9
031c:Ret  ucrtbase.getenv() retval=00000000 ret=0b58b3f9
...
--- snip ---

The workaround using external (shell) environment variable:

--- snip ---
$ NSPR_LOG_MODULES=all:5 WINEDEBUG=+relay wine iexplore.exe 
...
01d0:Call KERNEL32.SetEnvironmentVariableW(01836084
L"NSPR_LOG_MODULES",0031cfb0 L"all:1") ret=017c2ea1
...
01d0:Ret  KERNEL32.SetEnvironmentVariableW() retval=00000001 ret=017c2ea1 
...
01d0:Call ucrtbase.getenv(093d46b0 "NSPR_LOG_MODULES") ret=0938b3f9
01d0:Ret  ucrtbase.getenv() retval=001389d6 ret=0938b3f9
01d0:Call ucrtbase.strlen(001389d6 "all:5") ret=09385b52
01d0:Ret  ucrtbase.strlen() retval=00000005 ret=09385b52 
...
--- snip ---

'getenv' makes a copy of the environment variable block of the process on
startup. Any later changes using win32 API 'SetEnvironmentVariable' are not
reflected in the block of variables used by 'getenv' by design.

https://source.winehq.org/git/wine.git/blob/2d4dd4252b0cf6526b3cc8194cce642b16eb12f6:/dlls/msvcrt/environ.c#l28

--- snip ---
  28 /*********************************************************************
  29  *              getenv (MSVCRT.@)
  30  */
  31 char * CDECL getenv(const char *name)
  32 {
  33     char **env;
  34     unsigned int length=strlen(name);
  35 
  36     for (env = MSVCRT__environ; *env; env++)
  37     {
  38         char *str = *env;
  39         char *pos = strchr(str,'=');
  40         if (pos && ((pos - str) == length) && !_strnicmp(str,name,length))
  41         {
  42             TRACE("(%s): got %s\n", debugstr_a(name), debugstr_a(pos +
1));
  43             return pos + 1;
  44         }
  45     }
  46     return NULL;
  47 }
--- snip ---


https://source.winehq.org/git/wine.git/blob/2d4dd4252b0cf6526b3cc8194cce642b16eb12f6:/dlls/msvcrt/data.c#l402

--- snip ---
 402 /* INTERNAL: Since we can't rely on Winelib startup code calling
w/getmainargs,
 403  * we initialise data values during DLL loading. When called by a native
 404  * program we simply return the data we've already initialised. This also
means
 405  * you can call multiple times without leaking
 406  */
 407 void msvcrt_init_args(void)
 408 {
 409   OSVERSIONINFOW osvi;
 410 
 411   MSVCRT__acmdln = _strdup( GetCommandLineA() );
 412   MSVCRT__wcmdln = _wcsdup( GetCommandLineW() );
 413   initial_wargv  = cmdline_to_argv( GetCommandLineW(), &initial_argc );
 414   MSVCRT___argc  = initial_argc;
 415   MSVCRT___wargv = initial_wargv;
 416   MSVCRT___argv  = build_argv( initial_wargv );
 417 
 418   TRACE("got %s, wide = %s argc=%d\n", debugstr_a(MSVCRT__acmdln),
 419         debugstr_w(MSVCRT__wcmdln),MSVCRT___argc);
 420 
 421   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
 422   GetVersionExW( &osvi );
 423   MSVCRT__winver     = (osvi.dwMajorVersion << 8) | osvi.dwMinorVersion;
 424   MSVCRT__winmajor   = osvi.dwMajorVersion;
 425   MSVCRT__winminor   = osvi.dwMinorVersion;
 426   MSVCRT__osver      = osvi.dwBuildNumber;
 427   MSVCRT__osplatform = osvi.dwPlatformId;
 428   TRACE( "winver %08x winmajor %08x winminor %08x osver %08x\n",
 429           MSVCRT__winver, MSVCRT__winmajor, MSVCRT__winminor,
MSVCRT__osver);
 430 #ifdef _CRTDLL
 431   CRTDLL__baseversion_dll = (GetVersion() >> 16);
 432   CRTDLL__basemajor_dll   = CRTDLL__baseversion_dll >> 8;
 433   CRTDLL__baseminor_dll   = CRTDLL__baseversion_dll & 0xff;
 434 #endif
 435 
 436   MSVCRT__HUGE = HUGE_VAL;
 437   MSVCRT___setlc_active = 0;
 438   MSVCRT___unguarded_readlc_active = 0;
 439   MSVCRT__fmode = _O_TEXT;
 440 
 441   MSVCRT__environ = msvcrt_SnapshotOfEnvironmentA(NULL);
 442   MSVCRT___initenv = msvcrt_SnapshotOfEnvironmentA(NULL);
 443   MSVCRT___winitenv = msvcrt_SnapshotOfEnvironmentW(NULL);
...
--- snip ---

$ wine --version
wine-6.0-202-gc7de9f2daa8

Regards

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list