[Bug 40392] ComicRack 0.9.x (.NET 4.5 app) hangs/ crashes on startup when executing WMI query

wine-bugs at winehq.org wine-bugs at winehq.org
Sun Jan 8 12:15:50 CST 2017


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

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |focht at gmx.net
            Summary|ComicRack hangs with        |ComicRack 0.9.x (.NET 4.5
                   |builtin wbemprox (native    |app) hangs/crashes on
                   |wbemprox works around this) |startup when executing WMI
                   |                            |query

--- Comment #4 from Anastasius Focht <focht at gmx.net> ---
Hello folks,

confirming, the .NET app doesn't hang though - it cleanly crashes for me.
May be related to usage of MS .NET Framework instead of Wine-Mono.

The app wants .NET Framework 4.5 ('winetricks -q dotnet452' since I disabled
Wine-Mono by default).

--- snip ---
System.AccessViolationException: Attempted to read or write protected memory.
This is often an indication that other memory is corrupt.
   at System.Management.IWbemServices.GetObject_(String strObjectPath, Int32
lFlags, IWbemContext pCtx, IWbemClassObjectFreeThreaded& ppObject, IntPtr
ppCallResult)
   at System.Management.ManagementObject.Initialize(Boolean getObject)
   at System.Management.ManagementBaseObject.get_Properties()
   at System.Management.ManagementBaseObject.GetPropertyValue(String
propertyName)
   at System.Management.ManagementBaseObject.get_Item(String propertyName)
   at cYo.Common.Win32.MemoryInfo.get_CpuSpeedInHz()
   at cYo.Projects.ComicRack.Viewer.Program.AutoTuneSystem()
   at cYo.Projects.ComicRack.Viewer.Program.StartNew(String[] args)
   at cYo.Common.Runtime.SingleInstance.Run(String[] args)
   at cYo.Projects.ComicRack.Viewer.Program.Main(String[] args) 
--- snip ---

Winedbg:

--- snip ---
Unhandled exception: page fault on read access to 0xf9f40421 in 32-bit code
(0xf5e528e9).
Register dump:
 CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b
 EIP:f5e528e9 ESP:0033eba0 EBP:0033eba0 EFLAGS:00010286(  R- --  I S - -P- )
 EAX:f9f40421 EBX:00000000 ECX:0033ec58 EDX:00000000
 ESI:01528c08 EDI:0033ee04
...
Backtrace:
=>0 0xf5e528e9 strcmpW+0x10(str1=*** invalid address 0xf9f40421 ***,
str2="CPU0")
[/home/focht/projects/wine/wine.repo/src/include/wine/unicode.h:216] in
wbemprox (0x0033eba0)
  1 0xf5e52c32 eval_strcmp+0x4f(op=0x1, lstr=*** invalid address 0xf9f40421
***, rstr="CPU0", val=0x33ed08)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/query.c:84] in wbemprox
(0x0033ebc8)
  2 0xf5e5328a eval_binary+0x17b(table=0xf5e6f530, row=0x2, expr=0x66c9a04,
val=0x33ed08, type=0x33ed04)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/query.c:272] in wbemprox
(0x0033ec98)
  3 0xf5e5372d eval_cond+0x60(table=0xf5e6f530, row=0x2, cond=0x66c9a00,
val=0x33ed08, type=0x33ed04)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/query.c:375] in wbemprox
(0x0033ecd8)
  4 0xf5e48aea match_row+0x34(table=0xf5e6f530, row=0x2, cond=0x66c9a00,
status=0x33ed34)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/builtin.c:1156] in
wbemprox (0x0033ed18)
  5 0xf5e4c83d fill_processor+0x29d(table=0xf5e6f530, cond=0x66c9a00)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/builtin.c:2605] in
wbemprox (0x0033ef48)
  6 0xf5e53874 execute_view+0x5b(view=0x66c9a18)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/query.c:413] in wbemprox
(0x0033ef98)
  7 0xf5e53b21 exec_query+0x57(str="SELECT * FROM Win32_Processor WHERE
DeviceID="CPU0"", result=0x33f014)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/query.c:480] in wbemprox
(0x0033efc8)
  8 0xf5e5884a create_instance_enum+0x31(path=0x66c4d40, iter=0x33f014)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/services.c:412] in
wbemprox (0x0033eff8)
  9 0xf5e58899 get_object+0x35(object_path="Win32_Processor.DeviceID="CPU0"",
obj=0x33f114)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/services.c:426] in
wbemprox (0x0033f028)
  10 0xf5e589ec wbem_services_GetObject+0xe6(iface=<couldn't compute location>,
strObjectPath=<couldn't compute location>, lFlags=<couldn't compute location>,
pCtx=<couldn't compute location>, ppObject=<couldn't compute location>,
ppCallResult=<couldn't compute location>)
[/home/focht/projects/wine/wine.repo/src/dlls/wbemprox/services.c:454] in
wbemprox (0x0033f058)
...
  28 0x006c6b86 in clr (+0x166b85) (0x0033fdec)
  29 0x1000ffcc in mscoreei (+0xffcb) (0x0033fe28)
  30 0x79007f16 in mscoree (+0x7f15) (0x0033fe38)
  31 0x79004de3 in mscoree (+0x4de2) (0x0033fe58)
  32 0x7b46b703 start_process+0x128(peb=<couldn't compute location>)
[/home/focht/projects/wine/wine.repo/src/dlls/kernel32/process.c:1108] in
kernel32 (0x0033fe98)
...
0xf5e528e9 strcmpW+0x10
[/home/focht/projects/wine/wine.repo/src/include/wine/unicode.h:216] in
wbemprox: movzwl    0x0(%eax),%eax
216        while (*str1 && (*str1 == *str2)) { str1++; str2++; }
...
Wine-dbg>frame 4
1156        if (eval_cond( table, row, cond, &val, &type ) != S_OK)

Wine-dbg>info locals
0xf5e48ae9 match_row+0x34: (0033ed18)
    struct table* table=0xf5e6f530 (parameter [EBP+8])
    UINT row=0x2 (parameter [EBP+12])
    struct expr* cond=0x66c9a00 (parameter [EBP+16])
    enum fill_status* status=0x33ed34 (parameter [EBP+20])
    LONGLONG val=0x66c5f88000000c0 (local [EBP-16])
    UINT type=0x8 (local [EBP-20])

Wine-dbg>p *table

{name="Win32_Processor", num_cols=0x11, columns=0xf5e606c0, num_rows=0,
num_rows_allocated=0x8, data=" ", fill=0xf5e4c59f, flags=0,
entry={next=0xf5e6f57c, prev=0xf5e6f524}, refs=0x1}

Wine-dbg>frame 2
272            return eval_strcmp( expr->op, lstr, rstr, val );

Wine-dbg>info locals
0xf5e53289 eval_binary+0x17b: (0033ec98)
    struct table* table=0xf5e6f530 (parameter [EBP+8])
    UINT row=0x2 (parameter [EBP+12])
    struct complex_expr* expr=0x66c9a04 (parameter [EBP+16])
    LONGLONG* val=0x33ed08 (parameter [EBP+20])
    UINT* type=0x33ed04 (parameter [EBP+24])
    HRESULT lret=0 (local [EBP-36])
    HRESULT rret=0 (local [EBP-40])
    LONGLONG lval=0xfffffffff9f40421 (local [EBP-56])
    LONGLONG rval=0x66c99e0 (local [EBP-64])
    UINT ltype=0x8 (local [EBP-68])
    UINT rtype=0x8 (local [EBP-72])
    WCHAR* lstr=*** invalid address 0xf9f40421 *** (local [EBP-28])
    WCHAR* rstr="CPU0" (local [EBP-32])
    WCHAR --none--[21] lbuf={0xecc0, 0x33, 0xec34, 0x33, 0xd77b, 0x7bc5, 0,
0x11, 0x5fb8, 0x66c, 0, 0, 0x5f80, 0x66c, 0x30, 0, 0x6210, 0x66c, 0, 0, 0xec34}
(local [EBP-156])
    WCHAR --none--[21] rbuf={0x33, 0xb9e7, 0x7bc4, 0x64, 0x11, 0xffff, 0xffff,
0xec48, 0x33, 0xc498, 0x7bc4, 0x64, 0x11, 0xec60, 0x33, 0xecc0, 0x33, 0xeca8,
0x33, 0x4b2, 0x7bc6} (local [EBP-114])

272            return eval_strcmp( expr->op, lstr, rstr, val );
Wine-dbg>p lstr
"CPU1"
Wine-dbg>p rstr
"CPU0"
Wine-dbg>n


Wine-dbg>n
272            return eval_strcmp( expr->op, lstr, rstr, val );
Wine-dbg>p lstr
""
Wine-dbg>p rstr
"CPU0"
--- snip ---

Expression: 'SELECT * FROM Win32_Processor WHERE DeviceID="CPU0"'

Source:
http://source.winehq.org/git/wine.git/blob/1576dc3dd26c7bbb2ed8eb68f11799f1f1d8b6a2:/dlls/wbemprox/builtin.c#l2565

--- snip ---
static enum fill_status fill_processor( struct table *table, const struct expr
*cond )
2566 {
2567     static const WCHAR fmtW[] = {'C','P','U','%','u',0};
2568     WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13],
name[49] = {0}, version[50];
2569     struct record_processor *rec;
2570     UINT i, offset = 0, num_cores, num_logical_processors, count =
get_processor_count();
2571     enum fill_status status = FILL_STATUS_UNFILTERED;
2572 
2573     if (!resize_table( table, count, sizeof(*rec) )) return
FILL_STATUS_FAILED;
2574 
2575     get_processor_caption( caption );
2576     get_processor_id( processor_id );
2577     get_processor_manufacturer( manufacturer );
2578     get_processor_name( name );
2579     get_processor_version( version );
2580 
2581     num_logical_processors = get_logical_processor_count( &num_cores ) /
count;
2582     num_cores /= count;
2583 
2584     for (i = 0; i < count; i++)
2585     {
2586         rec = (struct record_processor *)(table->data + offset);
2587         rec->addresswidth           = get_osarchitecture() == os_32bitW ?
32 : 64;
2588         rec->caption                = heap_strdupW( caption );
2589         rec->cpu_status             = 1; /* CPU Enabled */
2590         rec->currentclockspeed      = get_processor_currentclockspeed( i
);
2591         rec->datawidth              = get_osarchitecture() == os_32bitW ?
32 : 64;
2592         rec->description            = heap_strdupW( caption );
2593         sprintfW( device_id, fmtW, i );
2594         rec->device_id              = heap_strdupW( device_id );
2595         rec->family                 = 2; /* Unknown */
2596         rec->manufacturer           = heap_strdupW( manufacturer );
2597         rec->maxclockspeed          = get_processor_maxclockspeed( i );
2598         rec->name                   = heap_strdupW( name );
2599         rec->num_cores              = num_cores;
2600         rec->num_logical_processors = num_logical_processors;
2601         rec->processor_id           = heap_strdupW( processor_id );
2602         rec->processortype          = 3; /* central processor */
2603         rec->unique_id              = NULL;
2604         rec->version                = heap_strdupW( version );
2605         if (!match_row( table, i, cond, &status ))
2606         {
2607             free_row_values( table, i );
2608             continue;
2609         }
2610         offset += sizeof(*rec);
2611     }
2612 
2613     TRACE("created %u rows\n", count);
2614     table->num_rows = count;
2615     return status;
2616 }
--- snip ---

You include rows from non-matching cases in final table row count which later
leads to access of freed memory for some record values (strings).

Solution is to use a separate 'row' variable that gets incremented each time a
row is matching.

Example:

http://source.winehq.org/git/wine.git/blob/1576dc3dd26c7bbb2ed8eb68f11799f1f1d8b6a2:/dlls/wbemprox/builtin.c#l2770

--- snip ---
static enum fill_status fill_os( struct table *table, const struct expr *cond )
2771 {
2772     struct record_operatingsystem *rec;
2773     enum fill_status status = FILL_STATUS_UNFILTERED;
2774     OSVERSIONINFOEXW ver;
2775     UINT row = 0;
...
2806     if (!match_row( table, row, cond, &status )) free_row_values( table,
row );
2807     else row++;
2808 
2809     TRACE("created %u rows\n", row);
2810     table->num_rows = row;
2811     return status;
2812 }
--- snip ---

Looks like 'fill_processor()' is not the only one with this problem .. you
might want to fix 'fill_printer()' as well.

$ du -sh ComicRackSetup09178.exe 
12M    ComicRackSetup09178.exe

$ sha1sum ComicRackSetup09178.exe 
c64f41f21590e41ba7274101b33d62ef93e135c8  ComicRackSetup09178.exe
$ wine --version

wine-2.0-rc3-14-g56959b1

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