[Bug 50409] New: Adobe Audition 2020 crashes on startup (msvcrt strftime_impl uses __lc_time_data struct WCHAR members but only ANSI members have been initialized by _Gettnames)
WineHQ Bugzilla
wine-bugs at winehq.org
Sun Dec 27 05:44:06 CST 2020
https://bugs.winehq.org/show_bug.cgi?id=50409
Bug ID: 50409
Summary: Adobe Audition 2020 crashes on startup (msvcrt
strftime_impl uses __lc_time_data struct WCHAR members
but only ANSI members have been initialized by
_Gettnames)
Product: Wine
Version: 6.0-rc4
Hardware: x86-64
OS: Linux
Status: NEW
Severity: normal
Priority: P2
Component: msvcrt
Assignee: wine-bugs at winehq.org
Reporter: focht at gmx.net
Distribution: ---
Hello folks,
continuation of bug 50401 ("Multiple Adobe products crash on unimplemented
function msvcp{100,110,120,140}.dll._Wcsxfrm (Audition CS6, Audition 2020)").
After providing a simple implementation it crashes:
--- snip ---
$ WINEDEBUG=+seh,+relay,+msvcrt,+msvcp wine ./Adobe\ Audition.exe >>log.txt
2>&1
...
0104:Call PE DLL (proc=0000000000B0D040,module=0000000000A90000
L"MSVCP140.dll",reason=PROCESS_ATTACH,res=000000000021FB00)
0104:trace:msvcp:DllMain (0x0000000000A90000, 1, 000000000021FB00)
...
0104:Call KERNEL32.CreateFileW(142a9c00 L"\\\\?\\C:\\users\\focht\\Application
Data\\Adobe\\Audition\\13.0\\logs\\Audition
Log.txt",c0000000,00000001,0021eec0,00000003,00000080,00000000) ret=1800cb243
...
0104:Ret KERNEL32.CreateFileW() retval=000000fc ret=1800cb243
...
0104:Call ucrtbase._Gettnames() ret=00ae7e6d
0104:trace:msvcrt:_Gettnames
0104:Call ntdll.RtlAllocateHeap(13f60000,00000000,000003d1) ret=00335a9e
0104:Ret ntdll.RtlAllocateHeap() retval=13f897a0 ret=00335a9e
0104:Ret ucrtbase._Gettnames() retval=13f897a0 ret=00ae7e6d
0104:trace:msvcp:_Timevec_ctor_timeptr (0000000013F89780 0000000013F897A0)
0104:trace:msvcp:locale_id_operator_size_t (0000000000B49908)
0104:trace:msvcp:locale__Locimp__Locimp_Addfac (0000000013F87280
0000000013F89770 7)
0104:trace:msvcp:locale_facet__Incref (0000000013F89770)
0104:trace:msvcp:codecvt_char__Getcat (0000000000000000 0000000000000000)
...
0104:trace:msvcp:time_put_char_put_format (0000000013F89770 000000000021ED98
000000000021ED28 000000000021EDC8 "%c")
0104:trace:msvcp:time_put_char_put (0000000013F89770 000000000021EC60
000000000021ED28 000000000021EDC8 c
(0000000013F89770 000000000021EC60 000000000021ED28 000000000021EDC8 c
Call ucrtbase._Strftime(0021ea20,00000040,0021ea1c "%c",0021edc8,13f897a0)
ret=00ae84b4
0104:trace:msvcrt:strftime_helper (000000000021EA20 64 %c 000000000021EDC8
0000000013F897A0 0000000000000000)
0104:Call ntdll.RtlAllocateHeap(13f60000,00000000,00000006) ret=00335a9e
0104:Ret ntdll.RtlAllocateHeap() retval=1404e270 ret=00335a9e
0104:Call ntdll.RtlAllocateHeap(13f60000,00000000,00000080) ret=00335a9e
0104:Ret ntdll.RtlAllocateHeap() retval=1404e2a0 ret=00335a9e
0104:Call KERNEL32.HeapFree(13f60000,00000000,1404e2a0) ret=00335a30
0104:Ret KERNEL32.HeapFree() retval=0021ed01 ret=00335a30
0104:Call KERNEL32.HeapFree(13f60000,00000000,1404e270) ret=00335a30
0104:Ret KERNEL32.HeapFree() retval=0021ed01 ret=00335a30
0104:Ret ucrtbase._Strftime() retval=ffffffffffffffff ret=00ae84b4
0104:trace:msvcp:basic_streambuf_char_sputc (000000000021ECA8 0)
0104:trace:msvcp:basic_streambuf_char__Pnavail (000000000021ECA8)
0104:Call
msvcp140.?pptr@?$basic_streambuf at DU?$char_traits at D@std@@@std@@IEBAPEADXZ(0021eca8)
ret=180040fdc
0104:trace:msvcp:basic_streambuf_char_pptr (000000000021ECA8)
0104:Ret
msvcp140.?pptr@?$basic_streambuf at DU?$char_traits at D@std@@@std@@IEBAPEADXZ()
retval=00000000 ret=180040fdc
0104:Call ucrtbase.malloc(00000020) ret=180242c1f
0104:Call ntdll.RtlAllocateHeap(13f60000,00000000,00000020) ret=00335a9e
0104:Ret ntdll.RtlAllocateHeap() retval=1404e270 ret=00335a9e
0104:Ret ucrtbase.malloc() retval=1404e270 ret=180242c1f
0104:Call ucrtbase.memcpy(1404e270,00000000,00000000) ret=180041086
0104:Ret ucrtbase.memcpy() retval=1404e270 ret=180041086
0104:Call
msvcp140.?_Pninc@?$basic_streambuf at DU?$char_traits at D@std@@@std@@IEAAPEADXZ(0021eca8)
ret=180041127
0104:trace:msvcp:basic_streambuf_char__Pninc (000000000021ECA8)
0104:Ret
msvcp140.?_Pninc@?$basic_streambuf at DU?$char_traits at D@std@@@std@@IEAAPEADXZ()
retval=1404e270 ret=180041127
0104:trace:msvcp:basic_streambuf_char_sputc (000000000021ECA8 -21)
0104:trace:msvcp:basic_streambuf_char__Pnavail (000000000021ECA8)
...
0104:trace:msvcp:basic_streambuf_char__Pninc (000000000021ECA8)
0104:trace:msvcp:basic_streambuf_char_sputc (000000000021ECA8 0)
0104:trace:msvcp:basic_streambuf_char__Pnavail (000000000021ECA8)
0104:trace:msvcp:basic_streambuf_char__Pninc (000000000021ECA8)
0104:trace:seh:dispatch_exception code=c0000005 flags=0 addr=0000000000AE84D1
ip=0000000000AE84D1 tid=0104
0104:trace:seh:dispatch_exception info[0]=0000000000000000
0104:trace:seh:dispatch_exception info[1]=0000000000289000
0104:trace:seh:dispatch_exception rax=0000000000000000 rbx=00000000ffffffff
rcx=0000000014dda61f rdx=0000000014dda620
0104:trace:seh:dispatch_exception rsi=000000000021ec60 rdi=000000000021eb20
rbp=000000000006a5e0 rsp=000000000021e9c0
0104:trace:seh:dispatch_exception r8=00000000000fffff r9=000000000021e538
r10=000000000021e101 r11=0000000000000246
0104:trace:seh:dispatch_exception r12=000000000021edaa r13=000000000021edc8
r14=000000000021edc8 r15=0000000000000000
0104:trace:seh:call_vectored_handlers calling handler at 000000007B011BA0
code=c0000005 flags=0
0104:trace:seh:call_vectored_handlers handler at 000000007B011BA0 returned 0
0104:trace:seh:RtlVirtualUnwind type 1 rip 0000000000AE84D1 rsp
000000000021E9C0
0104:trace:seh:dump_unwind_info **** func 583f0-584ff
0104:trace:seh:dump_unwind_info unwind info at 0000000000B3D628 flags 0 prolog
0xf bytes function 0000000000AE83F0-0000000000AE84FF
--- snip ---
Application _MSVCR_VER = 140
_Strftime() failing for '%c' seemed strange.
https://source.winehq.org/git/wine.git/blob/e377786a71c3b6eab5bc11c0b1c9c7c3dc309398:/dlls/msvcrt/time.c#l1081
--- snip ---
1081 static size_t strftime_impl(STRFTIME_CHAR *str, size_t max,
1082 const STRFTIME_CHAR *format, const struct tm *mstm,
1083 __lc_time_data *time_data, _locale_t loc)
1084 {
1085 size_t ret, tmp;
1086 BOOL alternate;
1087 int year = mstm ? mstm->tm_year + 1900 : -1;
1088
1089 if(!str || !format) {
1090 if(str && max)
1091 *str = 0;
1092 *_errno() = EINVAL;
1093 return 0;
1094 }
1095
1096 if(!time_data)
1097 time_data = loc ? loc->locinfo->lc_time_curr :
get_locinfo()->lc_time_curr;
1098
1099 for(ret=0; *format && ret<max; format++) {
1100 if(*format != '%') {
1101 if(_isleadbyte_l((unsigned char)*format, loc)) {
1102 str[ret++] = *(format++);
1103 if(ret == max) continue;
1104 if(!MSVCRT_CHECK_PMT(str[ret]))
1105 goto einval_error;
1106 }
1107 str[ret++] = *format;
1108 continue;
1109 }
1110
1111 format++;
1112 if(*format == '#') {
1113 alternate = TRUE;
1114 format++;
1115 }else {
1116 alternate = FALSE;
1117 }
1118
1119 if(!MSVCRT_CHECK_PMT(mstm))
1120 goto einval_error;
1121
1122 switch(*format) {
1123 case 'c':
1124 #if _MSVCR_VER>=140
1125 if(time_data == &cloc_time_data && !alternate)
1126 {
1127 tmp = strftime_impl(str+ret, max-ret, L"%a %b %e %T %Y",
mstm, time_data, loc);
1128 if(!tmp)
1129 return 0;
1130 ret += tmp;
1131 break;
1132 }
1133 #endif
1134 if(!strftime_format(str, &ret, max, mstm, time_data,
1135 alternate ? STRFTIME_TD(time_data, date) :
STRFTIME_TD(time_data, short_date)))
1136 return 0;
1137 if(ret < max)
1138 str[ret++] = ' ';
1139 if(!strftime_format(str, &ret, max, mstm, time_data,
STRFTIME_TD(time_data, time)))
1140 return 0;
1141 break;
...
1416 if(ret == max) {
1417 if(max)
1418 *str = 0;
1419 *_errno() = ERANGE;
1420 return 0;
1421 }
1422
1423 str[ret] = 0;
1424 return ret;
1425
1426 einval_error:
1427 *str = 0;
1428 return 0;
1429 }
--- snip ---
_MSVCR_VER >= 140 case.
'strftime_format( ... STRFTIME_TD(time_data, short_date))' failed while
'strftime_format( ... STRFTIME_TD(time_data, time)))' partially worked (by
chance), leading to output buffer content:
--- snip ---
01404E290 00 00 00 00 00 00 00 00 88 00 00 00 55 53 45 08 ............USE.
01404E2A0 20 00 31 00 32 00 3A 00 33 00 33 00 3A 00 30 00 .1.2.:.3.3.:.0.
01404E2B0 30 00 20 00 41 64 74 80 92 F8 13 00 00 00 00 00 0. .Adt..ø......
01404E2C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
01404E2D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
--- snip ---
str = " 12:33:00 " = 10 wchars, rest is garbage (uninit).
ret = 0xe -> str[0xe] = null terminate behind garbage
'strftime_format( .. STRFTIME_TD(time_data, short_date))' fails due to
'time_data->shortdate' being a NULL string.
https://source.winehq.org/git/wine.git/blob/e377786a71c3b6eab5bc11c0b1c9c7c3dc309398:/dlls/msvcrt/msvcrt.h#l47
--- snip ---
47 typedef struct __lc_time_data {
48 union {
49 const char *str[43];
50 struct {
51 const char *short_wday[7];
52 const char *wday[7];
53 const char *short_mon[12];
54 const char *mon[12];
55 const char *am;
56 const char *pm;
57 const char *short_date;
58 const char *date;
59 const char *time;
60 } names;
61 } str;
62 #if _MSVCR_VER < 110
63 LCID lcid;
64 #endif
65 int unk;
66 int refcount;
67 union {
68 const wchar_t *wstr[43];
69 struct {
70 const wchar_t *short_wday[7];
71 const wchar_t *wday[7];
72 const wchar_t *short_mon[12];
73 const wchar_t *mon[12];
74 const wchar_t *am;
75 const wchar_t *pm;
76 const wchar_t *short_date;
77 const wchar_t *date;
78 const wchar_t *time;
79 } names;
80 } wstr;
81 #if _MSVCR_VER >= 110
82 const wchar_t *locname;
83 #endif
84 char data[1];
85 } __lc_time_data;
--- snip ---
The log again:
--- snip ---
0104:Call ucrtbase._Gettnames() ret=00ae7e6d
0104:trace:msvcrt:_Gettnames
0104:Call ntdll.RtlAllocateHeap(13f60000,00000000,000003d1) ret=00335a9e
0104:Ret ntdll.RtlAllocateHeap() retval=13f897a0 ret=00335a9e
0104:Ret ucrtbase._Gettnames() retval=13f897a0 ret=00ae7e6d
0104:trace:msvcp:_Timevec_ctor_timeptr (0000000013F89780 0000000013F897A0)
...
--- snip ---
time_put_char__Getcat
-> time_put_char_ctor_locinfo
-> time_put_char__Init
-> _Locinfo__Gettnames
-> _Gettnames
https://source.winehq.org/git/wine.git/blob/e377786a71c3b6eab5bc11c0b1c9c7c3dc309398:/dlls/msvcrt/locale.c#l793
--- snip ---
793 /*********************************************************************
794 * _Gettnames (MSVCRT.@)
795 */
796 void* CDECL _Gettnames(void)
797 {
798 __lc_time_data *ret, *cur = get_locinfo()->lc_time_curr;
799 unsigned int i, len, size = sizeof(__lc_time_data);
800
801 TRACE("\n");
802
803 for(i=0; i<ARRAY_SIZE(cur->str.str); i++)
804 size += strlen(cur->str.str[i])+1;
805
806 ret = malloc(size);
807 if(!ret)
808 return NULL;
809 memcpy(ret, cur, sizeof(*ret));
810
811 size = 0;
812 for(i=0; i<ARRAY_SIZE(cur->str.str); i++) {
813 len = strlen(cur->str.str[i])+1;
814 memcpy(&ret->data[size], cur->str.str[i], len);
815 ret->str.str[i] = &ret->data[size];
816 size += len;
817 }
818
819 return ret;
820 }
--- snip ---
The ANSI parts of the structure get copied - as the function name implies.
Tidbit: A wide-char variant exists as well but is nowhere used. It also seems
wrong because it calls the ANSI _Gettnames() which does not copy WCHAR members.
--- snip ---
822 #if _MSVCR_VER >= 110
823 /*********************************************************************
824 * _W_Gettnames (MSVCR110.@)
825 */
826 void* CDECL _W_Gettnames(void)
827 {
828 return _Gettnames();
829 }
830 #endif
--- snip ---
Back to original problem. At the point of 'strftime_impl', '__lc_time_data'
contains only the ANSI members initialized but the 'STRFTIME_TD' macro
references WCHAR members for _MSVCR_VER > 90.
https://source.winehq.org/git/wine.git/blob/e377786a71c3b6eab5bc11c0b1c9c7c3dc309398:/dlls/msvcrt/time.c#l853
--- snip ---
853 #if _MSVCR_VER <= 90
854 #define STRFTIME_CHAR char
855 #define STRFTIME_TD(td, name) td->str.names.name
856 #else
857 #define STRFTIME_CHAR wchar_t
858 #define STRFTIME_TD(td, name) td->wstr.names.name
859 #endif
--- snip ---
The code was introduced here:
https://source.winehq.org/git/wine.git/commitdiff/c37268f0aa6da3825aa11551537b8e18aa62bdca
("msvcrt: Use correct __lc_time_data fields in strftime functions.")
It's also referenced by bug 50151 ("World of Tanks fails to launch if
LC_LANG/LC_ALL are set ja_JP") as regression commit.
I made a separate case here because:
* the app can't reach this code yet (blocker bugs) = nothing to "regress"
* doesn't depend on the locale setting
* exhibits a different user visible sympthom
$ sha1sum AdobeAudition13All.zip
b2800e4fd28f3c669cd0b3754ec11a9e8e18cee1 AdobeAudition13All.zip
$ du -sh AdobeAudition13All.zip
296M AdobeAudition13All.zip
$ wine --version
wine-6.0-rc4
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