Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken image in example ex_html.exe on Windows 8 and 8.1 #13

Open
mity opened this issue Nov 7, 2013 · 9 comments
Open

Broken image in example ex_html.exe on Windows 8 and 8.1 #13

mity opened this issue Nov 7, 2013 · 9 comments
Labels

Comments

@mity
Copy link
Owner

mity commented Nov 7, 2013

When running ex_html.exe built with mingw-w64 on Windows 8 and 8.1, a PNG image is not shown in the HTML page.

@mity
Copy link
Owner Author

mity commented Nov 7, 2013

screenshot

@mity
Copy link
Owner Author

mity commented Nov 7, 2013

Investigation showed the following facts:

  • When built with MSVC 2010 Express, the problem does not occur.
  • On Windows 7 and XP it does not occur.
  • The problem disappears if the ex_html.exe does not have manifest (RT_MANIFEST), or if the manifest is smaller then 512 bytes.
  • By adding more HTML resources or by reodering them (involves renaming them as they are sorted by windres), different resource may be made broken instead.
  • The resource seems to be correct in that sense that if the ex_html.exe uses FindResource() + LoadResource() + LockResource() and saves the resource into the file (at end of the program), it is valid PNG image binary equal to the source one. Perhaps MSHTML.DLL accesses it in a different way rather then using those Win32 functions???

@mity
Copy link
Owner Author

mity commented Nov 11, 2013

More observations:

  • The issue does not occur when the resource is in a module not linked into the .EXE. It is enough to rename the original .exe to 'foo.exe' and change the URLs in the original resources accordingly (to begin with res://foo.exe/)

@mity mity added the bug label Jun 23, 2014
@mity
Copy link
Owner Author

mity commented Jul 18, 2014

Even more observations. It seems that many conditions have to be met in order to reproduce the bug:

  • OS is Win 8 or 8.1.
  • ex_html.exe must be built with gcc toolchain (gcc + binutils). ex_html.exe built with MSVC does not exhibit the issue (even when used together with mCtrl.dll built with gcc)
  • Both 32-bit and 64-bit builds have the bug.
  • ex_html.exe must have the application manifest resource (removing it fixes the issue).
  • The web browser must be embedded in the process. Accessing the resource from other process (e.g. from a renamed copy of ex_html.exe with changed URLs referring to resources in the broken ex_html.exe) does not lead to the bug.
  • It is 1st run of ex_html.exe (since reboot, after (re)built, copied, or at least touched). Subsequent runs do not trigger the issue.

Gosh. This issue is big mystery to me.

As the issue seems to be related to layout of resources in .rsrc section, I performed several analyzes and experiments.

  1. Updated ex_html.exe to access the "broken" resources with FindResource() + LoadResource() on app. exit (i.e. after the bug happens) and saved them to a file. They are genuine and same as the "unbroken" originals.
  2. Commented the image resource in resource script. Other resource (the doc.html) got broken.
  3. Placed various padding resources (custom resources created from zero-filled blocks of given length, never loaded by the program). Seems that resource of type 23 (i.e. RT_MANIFEST - 1) which is long enough "fixes" the issue.
  4. Retried (3) and (2) together. Required length of the padding differs.
  5. Retried (2), (3) and (4) with 32 as well as 64-bit builds, and with various compile time options. For given resource script, the minimal length to "fix" the issue is always constant.
  6. Tried to edit resources in "broken" ex_html.exe with resource hacker: Added a dummy resource, saved and then removed it back. This way, I assume, I forced the Windows API (BeginUpdateResource() + related functions). Result was not same as that one of RC.EXE but much closer then windres.exe. Again this "fixed" the issue.

Is it possible there is incompatibility between windres, and some part of Windows 8 (which may be the embedded browser, dynamic loader which surely interprets the manifest or whatever)???

Manually analyzed hex-dump of the .rsrc section, both from ex_html.exe built with gcc and MSVC:

@mity
Copy link
Owner Author

mity commented Jul 18, 2014

Tried once again to verify correctness of mCtrl.dll + ex_html.exe code:

  • Asked friend to make an independent review MC_WC_HTML control implementation as well as code of ex_html.exe. No output.
  • Run with AppVerifier. No usable output.
  • Run with DrMemory. On Windows XP and 7, it does not find any issue. On Windows 8.1 it crashes with ex_html.exe.
  • Scanned with Coverity. No issue.
  • Tried to remove as much non-essential code from MC_WC_HTML as possible. Bug still happens.

@mity
Copy link
Owner Author

mity commented Jul 18, 2014

Enabled HTML traces (-DHTML_DEBUG=1), run ex_html.exe multiple times. When compared the 1st run (when the bug happens) and subsequent runs (when it does not):

  • All logged calls to COM interfaces implemented in html.c are same and it the very same order.
  • Strangely there is only one difference in the logs (when ignoring thread ID and timestamps of logged messages): The 1st run logs 10 times about DllMain(DLL_THREAD_ATTACH) while subsequent runs do 11 times. The 6th (sic!) started thread is the one that is missing in the 1st run.
  • Verified that all calls to the COM objects implemented in html.c are performed in the context of the main thread (as of ex_html.exe).

@mity
Copy link
Owner Author

mity commented Jul 18, 2014

What the hell is going on??

@mity
Copy link
Owner Author

mity commented Jul 19, 2014

Tried one more intersting experiment:

  1. Compiled ex_html.rc into ex_html.rc.obj by windres from the mingw-w64 toolchain.
  2. Compiled ex_html.c into ex_html.c.obj by MSVC 12 compiler.
  3. Linked the two together with MSVC 12 linker.

The bug is still there. By this I consider more or less proved the issue is about incompatibility of windres from GNU binutils and something in Windows 8 or 8.1. Given the bug happens only on the 1st run, it may involve some caching in some Windows subsystem.

Perhaps dynamic loader somehow and very subtly breaks state of loaded ex_html.exe image when accessing the application manifest in it (in a way colliding only with resource layout as output by windres but not RC.EXE. Arguably, Windows might cache the manifest for next app. starts so the subsequent starts do not trigger the bug. But this paragraph is pure speculation.

@mity
Copy link
Owner Author

mity commented Jul 19, 2014

Reported in binutils bugzilla:
https://sourceware.org/bugzilla/show_bug.cgi?id=17184

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant