Last Comment Bug 350616 - Need to figure out VC8 CRT issues with the XULRunner stub (and with embedding)
: Need to figure out VC8 CRT issues with the XULRunner stub (and with embedding)
Product: Toolkit Graveyard
Classification: Graveyard
Component: XULRunner (show other bugs)
: unspecified
: x86 Windows XP
: -- normal with 3 votes (vote)
: mozilla1.9alpha1
Assigned To: Ted Mielczarek [:ted.mielczarek]
Depends on: 334528 394190
Blocks: 373047 371359
  Show dependency treegraph
Reported: 2006-08-29 12:16 PDT by Benjamin Smedberg [:bsmedberg]
Modified: 2016-02-12 08:12 PST (History)
27 users (show)
See Also:
QA Whiteboard:
Iteration: ---
Points: ---

hack (1.87 KB, patch)
2006-11-06 08:53 PST, Jonathan Watt [:jwatt]
no flags Details | Diff | Splinter Review
hack with lpAssemblyDirectory instead of SetCurrentDirectory (components fail to load) (1.40 KB, patch)
2006-11-06 11:26 PST, Jonathan Watt [:jwatt]
no flags Details | Diff | Splinter Review
current diff (activation context + SetDllDirectory) (3.06 KB, patch)
2006-11-09 02:17 PST, Jonathan Watt [:jwatt]
no flags Details | Diff | Splinter Review
embed manifests in everything (5.23 KB, patch)
2007-04-23 13:23 PDT, Ted Mielczarek [:ted.mielczarek]
benjamin: review+
benjamin: approval1.9+
Details | Diff | Splinter Review
embed manifests in nspr libs (4.73 KB, patch)
2007-04-23 13:24 PDT, Ted Mielczarek [:ted.mielczarek]
no flags Details | Diff | Splinter Review
embed manifests in nspr libs, use $(MT) (48.74 KB, patch)
2007-06-07 07:45 PDT, Ted Mielczarek [:ted.mielczarek]
wtc: review+
Details | Diff | Splinter Review
embed manifests in nspr libs, use $(MT) (as checked in) (4.77 KB, patch)
2007-06-09 09:30 PDT, Wan-Teh Chang
no flags Details | Diff | Splinter Review
embed manifests in nspr tests (903 bytes, patch)
2007-06-09 10:28 PDT, Wan-Teh Chang
ted: review+
Details | Diff | Splinter Review

Description Benjamin Smedberg [:bsmedberg] 2006-08-29 12:16:31 PDT
Followup to bug 334528: even after that lands, the XULRunner stub can't load gecko correctly. The situation is something like this:

c:\Program Files\MyApplication\xulrunner-stub.exe, when launched, tries to dynamically load
c:\Program Files\Mozilla\XULRunner 1.9a1\xul.dll (and xpcom.dll, and other things). But because the CRT is at c:\Program Files\Mozilla\XULRunner 1.9a1 and not at c:\Program Files\MyApplication, the loader doesn't find it and the app doesn't start.

Ted, I need your help with this one. Is there any way to embed a manifest in xul.dll (and nspr4.dll and the other DLLs in question) which tells the loader to look in the same directory as the DLL for the CRT assembly, instead of looking in the application directory? I'd like to avoid the Activation Context goop that we did for the installer in bug 328579
Comment 1 Ted Mielczarek [:ted.mielczarek] 2006-08-29 12:36:22 PDT
AIUI, if you embed a manifest at resource ID 2, the system will look for the CRT assembly in the same directory as the DLL.  As long as you don't intend to use these DLLs in any other fashion, that's ok.

The problem we had with the installer bug was that we used the same DLLs in two different fashions: once for the installer, where they were extracted to a temp dir with the CRT manifest/assemblies in the same directory, and then again in appdir/components/, where the CRT was in appdir/.

Reference: (specifically the last paragraph)
Comment 2 Ted Mielczarek [:ted.mielczarek] 2006-08-29 12:39:26 PDT
I forgot to mention, the patch from bug 328579 gives you the ability to say:

In your before you include
Comment 3 Benjamin Smedberg [:bsmedberg] 2006-08-29 12:40:43 PDT
No component libraries are involved, only library DLLS that would live next to the CRT.
Comment 4 Ted Mielczarek [:ted.mielczarek] 2006-08-29 12:43:13 PDT
Then you can do this safely by embedding the manifest at ID 2, and XULRunner app authors including binary components will have to make sure not to embed a manifest at all in their components.
Comment 5 Benjamin Smedberg [:bsmedberg] 2006-08-29 12:45:07 PDT
What about NSPR]NSS? Do they currently embed a manifest?
Comment 6 Ted Mielczarek [:ted.mielczarek] 2006-08-29 12:53:19 PDT
Nope.  Currently, EXEs get a manifest at resource ID 1, and DLLs don't get a manifest at all unless they ask for it with that Makefile define.  The only places that happens right now are in XPInstall and MSAA (from bug 338807 ).
Comment 7 Ted Mielczarek [:ted.mielczarek] 2006-08-29 12:55:21 PDT
Oh, one more note:  I believe that once one DLL gets loaded with an activation context, then that becomes the current activation context, so any other DLLs loaded without one will use the existing one.  If you can guarantee that xul.dll or xpcom.dll or whatever will get loaded first, then I think you can get away with just embedding the manifest in that one DLL.

I could be off base, but it's easy enough to test.  Just use mt.exe from the commandline and embed a manifest in your dll, and see if it works.
Comment 8 Ted Mielczarek [:ted.mielczarek] 2006-08-30 09:51:30 PDT
Additionally, if I'm wrong on that last point, and you do need to embed a manifest in every single DLL to make this work, and getting that into NSPR/NSS is a problem, I think copying the activation context magic from xpinstall wouldn't be too bad.  You would basically need to stick this block of code: (modified a bit)
Right before here:
Comment 9 Benjamin Smedberg [:bsmedberg] 2006-08-30 09:55:24 PDT
Yeah... I'd prefer a solution that didn't require that, because that require every embedder to do it, as well as every future version of the stub. I'm going to see what we can do to get the manifests embedded in NSPR, because everything else depends on the NSPR libs being loaded first.
Comment 10 Ludovic Hirlimann [:Usul] 2006-11-02 09:10:12 PST
(In reply to comment #9)
>  I'm going
> to see what we can do to get the manifests embedded in NSPR, because everything
> else depends on the NSPR libs being loaded first.

Benja;in, did you progress on that ?
Comment 11 Benjamin Smedberg [:bsmedberg] 2006-11-02 13:06:07 PST
No, it's P3 which means that it's well below my radar right now.
Comment 12 Jonathan Watt [:jwatt] 2006-11-03 09:54:29 PST
Seems that NSS does now embed a manifest. See bug 353475.
Comment 13 Jonathan Watt [:jwatt] 2006-11-03 14:28:02 PST
Embedding a manifest in nspr4.dll simply reduced the number of:

  This application has failed to start because MSVCR80D.dll was not found.
  Re-installing the application may fix this problem.

popups from six to five (non-libxul build). All six popups are eliminated when manifests are embedded in each of:


but then DLLs from the xulrunner/components directory fail to load. I get lots of:

  nsNativeModuleLoader::LoadModule("...\xulrunner\components\caps.dll") - load
  FAILED, rv: 80004003, error:
          error 126

for DLLs such as caps.dll, necko.dll, chrome.dll and tkitcmps.dll before the process dies. Embedding a manifest at resource ID 2 in caps.dll seems to get it to load even though the CRT isn't beside that DLL. I'm not sure how to proceed other than to embed a manifest in all DLLs the app can load. Thoughts?
Comment 14 Jonathan Watt [:jwatt] 2006-11-05 03:42:32 PST
I believe that confirms my observations that this isn't as simple as embedding a manifest once in nspr4.dll (only embedding at resource ID 1 sets the process default, but embedding at resource ID 1 isn't valid for DLLs).
Comment 15 Jonathan Watt [:jwatt] 2006-11-06 07:48:57 PST
Doing as Ted suggests in comment 8 doesn't seem to be enough. It appears to get all the DLLs in the xulrunner directory loading correctly, but all the DLLs in xulrunner/components fail.
Comment 16 Jonathan Watt [:jwatt] 2006-11-06 07:54:55 PST
Programmatically making the xulrunner directory the current directory as well as doing the activation context stuff seems to fix things. DLLs from appdir/components seem to load fine too. I'm going to play with this some more and then I'll attach a patch.
Comment 17 Benjamin Smedberg [:bsmedberg] 2006-11-06 07:56:25 PST
You must not change the current directory. It will break all kinds of commandline handling behaviors.
Comment 18 Jonathan Watt [:jwatt] 2006-11-06 08:53:27 PST
Created attachment 244810 [details] [diff] [review]

In that case I won't bother trying to make the setting of the directory cross platform. Here's what I have, nevertheless. I embedded the manifest in xpcom.dll instead of nspr4.dll simply because I couldn't figure out how to use the build system of the latter to do the embedding.
Comment 19 Ted Mielczarek [:ted.mielczarek] 2006-11-06 09:12:41 PST
Comment on attachment 244810 [details] [diff] [review]

>+  // change the current directory to the GRE directory
>+  SetCurrentDirectory(greDir);
>+  // now put XPCOM_DLL back on the end of greDir
>+  if (lastSlash) {
>+    *lastSlash = PATH_SEPARATOR_CHAR;
>+  }
>+  ACTCTXA actctx;
>+  ULONG_PTR ulpActivationCookie;
>+  /* Windows XP + Visual C++ 8 requires proper
>+   * Side by Side configuration, which means
>+   * we have to have a manifest to create an
>+   * Activation Context so we can locate the
>+   * VC8 runtime.
>+   */
>+  memset(&actctx, 0, sizeof(actctx));
>+  actctx.cbSize = sizeof(actctx);
>+  actctx.lpSource = (LPCSTR)greDir;
>+  actctx.lpResourceName = MAKEINTRESOURCE(17);

I think instead of using SetCurrentDirectory, you may be able to do like:

actctx.lpAssemblyDirectory = greDir;

Can you give that a try?
Comment 20 Ted Mielczarek [:ted.mielczarek] 2006-11-06 09:24:11 PST
Of course that code isn't completely correct, you'll probably need to strcpy the greDir where you do the SetCurrentDirectory there.
Comment 21 Jonathan Watt [:jwatt] 2006-11-06 09:57:32 PST
Still the failures trying to load anything from xulrunner/components I'm afraid.
Comment 22 Ted Mielczarek [:ted.mielczarek] 2006-11-06 10:07:46 PST
Just for completeness, can you post your updated patch you tried?
Comment 23 Jonathan Watt [:jwatt] 2006-11-06 11:26:59 PST
Created attachment 244824 [details] [diff] [review]
hack with lpAssemblyDirectory instead of SetCurrentDirectory (components fail to load)

Sure, best to check I'm not doing something silly. ;-) Stepping through the code in the debugger everything looks fine (paths look good). However, at this point in the code:,908#892

although the absolute path to the DLL in wname looks fine, h gets set to NULL with error 126 (ERROR_MOD_NOT_FOUND). See

Adding the SetCurrentDirectory change "fixes" things so that the DLLs in xulrunner/components load again. Since the ActivateActCtx call fixes the loading of DLLs from the xulrunner directory, I'm not sure what the problem with the DLLs in the components directory is. I don't believe they're failing because the CRT isn't found though. I think it must be something else.
Comment 24 Jonathan Watt [:jwatt] 2006-11-06 12:09:15 PST
Ah. If I replace SetCurrentDirectory with SetDllDirectory, things work too. This is even though I pass SetDllDirectory the xulrunner directory, and not the xulrunner/components directory.
Comment 25 Ted Mielczarek [:ted.mielczarek] 2006-11-06 12:10:32 PST
You are running on WinXP, right?
Comment 26 Jonathan Watt [:jwatt] 2006-11-06 12:11:36 PST
Note that to build with SetDllDirectory you need to add the following line before the windows.h include:

#define _WIN32_WINNT 0x0502
Comment 27 Jonathan Watt [:jwatt] 2006-11-06 12:12:04 PST
WinXP SP2, right.
Comment 28 Benjamin Smedberg [:bsmedberg] 2006-11-06 12:19:10 PST
Since SetDllDirectory is not available in win2k, we'd need to dynamically load it (but that's ok, since we don't have this problem except in winxp+). We could even do it from the app itself, so that we don't have to change the stub.
Comment 29 Jonathan Watt [:jwatt] 2006-11-06 12:30:42 PST
Great. It would be really nice to get a handle on _why_ the above attempts work/fail first though. :-)
Comment 30 Ted Mielczarek [:ted.mielczarek] 2006-11-06 12:45:15 PST
What I assume is that the CRT DLLs are not in the search path unless a) the dll you're trying to load is in that same dir, or b) you've called SetDllDirectory.

However, the more I read about the SxS stuff, the less I understand.

It looks like my suggestion from comment #19 has no effect, so you can just remove that and use your SetDllDirectory fix along with the original activation context magic, and things should work.

Comment 31 Jonathan Watt [:jwatt] 2006-11-06 14:38:50 PST
I'm not convinced that finding the CRT DLLs is the problem. Maybe it is, but then I'd have expected similar errors loading the DLLs under the components directory as we get when loading the DLLs under the xulrunner directory without the activation context stuff. I'll investigate further tomorrow.

I certainly sympathize with your feelings on the SxS stuff. I can't get anything more than a fuzzy grip on how this stuff works from my reading of the docs.

Regarding your suggestion in comment 19, I think whether it works or not, it's the right thing to do so I'd rather leave it in.

Benjamin, assuming doing the activation and dll path stuff is all good, where do you want the various pieces put? I was thinking putting them in XPCOMGlueStartup should get things working and save embedders from having to know about this. That files doesn't reach out to system.dll right now, but hopefully making it do so isn't a problem.
Comment 32 Jonathan Watt [:jwatt] 2006-11-09 02:17:41 PST
Created attachment 245081 [details] [diff] [review]
current diff (activation context + SetDllDirectory)

A couple of people have mailed me privately to ask for my current diff. It's not hard to derive it from the comments above, but I might as well attach it I guess.
Comment 33 Jonathan Watt [:jwatt] 2006-11-09 02:49:45 PST
Gah! So because the stub is inexplicably broken even for people with the CRT in WinSxS, when I got it to work on my machine (which has the CRT in WinSxS) I forgot to test on a machine without Visual Studio installed. My current efforts only manage to get the CRT in WinSxS recognized. Even though it's all about setting search paths/activation contexts to the xulrunner directory! The CRT bundled with XULRunner still isn't found, so this doesn't fix things for the general populous. Now I'm even more confused than before.

Anyway, this hack allows our guys to continue with their work on their VS installed machines for now, and I have too many other pressing things to look into this further. If someone has ideas or insight I'll happily run tests for you, or if someone wants to pick this up and run with it, feel free.
Comment 34 Tom Clowers 2007-03-21 09:35:34 PDT
Is there anything new to add on this? Will this need to be solved in order to build Firefox running on XULRunner?
Comment 35 Tom Brunet 2007-04-17 13:12:09 PDT
I'm doing accessibility work for a xulrunner based app and wanted to take 1.9a4 for a spin to see what's been fixed/broken.  Unfortunately, I immediately received the R6034 error.  Is there an update to the target milestone (still listed as 1.9a1)?  And doesn't this qualify for 'Blocker' or at least 'Critical' severity since the application can't run at all?
Comment 36 Ted Mielczarek [:ted.mielczarek] 2007-04-23 07:32:19 PDT
Ok, I've done some investigation.  XULRunner on windows doesn't ship any binary components in components/.  Therefore, if we just embed a manifest in all of our DLLs, we should be in good shape.  I tested this with the JavaXPCOM tests and the XR stub.  I will have to patch NSPR to ensure that it gets manifests in everything.  XR app authors and extension authors will have to statically link to the CRT in any components they author, but I think this is a workable situation.

Comment 37 Ted Mielczarek [:ted.mielczarek] 2007-04-23 13:23:34 PDT
Created attachment 262548 [details] [diff] [review]
embed manifests in everything
Comment 38 Ted Mielczarek [:ted.mielczarek] 2007-04-23 13:24:30 PDT
Created attachment 262549 [details] [diff] [review]
embed manifests in nspr libs

And for NSPR as well.
Comment 39 Wan-Teh Chang 2007-06-06 18:15:15 PDT
Comment on attachment 262549 [details] [diff] [review]
embed manifests in nspr libs

This patch looks okay.  I'd prefer a patch that's similar to the NSS patch, which uses a variable named MT whose value is mt.exe.
Comment 40 Ted Mielczarek [:ted.mielczarek] 2007-06-07 07:45:09 PDT
Created attachment 267580 [details] [diff] [review]
embed manifests in nspr libs, use $(MT)

Is this better?
Comment 41 Wan-Teh Chang 2007-06-07 18:38:35 PDT
Comment on attachment 267580 [details] [diff] [review]
embed manifests in nspr libs, use $(MT)

Comment 42 Wan-Teh Chang 2007-06-07 18:44:58 PDT
Comment on attachment 267580 [details] [diff] [review]
embed manifests in nspr libs, use $(MT)

Ted, just curious: what do the ;1 and ;2 at the end of the
-OUTPUTRESOURCE option mean?  I noticed that
mozilla/xpinstall/stub/ were using ;17 before.
Comment 43 Ted Mielczarek [:ted.mielczarek] 2007-06-08 05:37:11 PDT
That's the resource ID where the manifest is embedded.  Windows expects to read manifests at ID 1 for executables, and 2 for DLLs (usually, although you can do other things).  Anything above 16 is left for user-defined activities.  We were using 17 because we had some code in xpistub to manually create an activation context and load the manifest into it.  Since we're no longer using the xpinstaller, we don't need that anymore.  If anyone still needed it, they could make it load from resource ID 2 anyway.

Thanks for the review!
Comment 44 Ted Mielczarek [:ted.mielczarek] 2007-06-08 05:48:38 PDT
Comment on attachment 262548 [details] [diff] [review]
embed manifests in everything

Checked in on trunk.
Comment 45 Wan-Teh Chang 2007-06-09 09:30:34 PDT
Created attachment 267800 [details] [diff] [review]
embed manifests in nspr libs, use $(MT) (as checked in)

I made some minor changes.  I've checked in this patch on the
NSPR trunk (NSPR 4.7) and will check this in on the
NSPRPUB_PRE_4_2_CLIENT_BRANCH when the Mozilla trunk reopens.
Comment 46 Wan-Teh Chang 2007-06-09 10:28:58 PDT
Created attachment 267803 [details] [diff] [review]
embed manifests in nspr tests

We missed the NSPR test programs, which are built with a
rule in mozilla/nsprpub/pr/tests/  This patch
takes care of that makefile rule.
Comment 47 Wan-Teh Chang 2007-06-09 10:31:29 PDT
Comment on attachment 267803 [details] [diff] [review]
embed manifests in nspr tests

Note that I use -OUTPUTRESOURCE:$@\;1 to build the NSPR
test programs.
Comment 48 Robert Kaiser 2007-06-09 16:03:16 PDT
I heavily suspect this has caused SeaMonkey Ts to increase from ~760ms to ~880ms on Windows (see )

We currently have no test data for Firefox, but one reason for that may again be this checkin (that is the one in comment #44) as suggested in bug 383875
Comment 49 Robert Kaiser 2007-06-09 17:25:59 PDT
Sorry for yet another comment, but that SeaMonkey perf data is backed by the other Windows tinderbox in SeaMonkey-Ports which went from ~2200ms to ~2600 on Ts, while the Mac box there and the Linux both on the SeaMonkey tinderbox page all stayed unchanged. Also other perf data than Ts stayed unchanged.

So overall, we have a 15-20% Windows-only Ts regression for SeaMonkey.
Comment 50 :Gavin Sharp [email:] 2007-06-09 23:24:25 PDT
I backed out attachment 262548 [details] [diff] [review] to see if it would fix the perf test machine bustage that's keeping the tree closed (bl-bldxp01). It cycled once, and still crashed. I've triggered a clobber to see if that will fix it, but won't be able to stay around until we get the results (the cycle time is at least a couple of hours).
Comment 51 Phil Ringnalda (:philor) 2007-06-09 23:39:01 PDT
And while the backout didn't make bl-bldxp01 happy, it did drop Ts on sea-win32-tbox from 891 the run before to 750 the run after, so more than "heavily suspect."
Comment 52 Joe Sabash [:JoeS1] 2007-06-10 07:05:44 PDT
The backout seems to fixed Thunderbird trunk also.
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a6pre) Gecko/20070610 Thunderbird/3.0a1pre ID:2007061003 [cairo]
Starts and runs fine here, winxp sp2 (previously crashed on startup)
Comment 53 Ted Mielczarek [:ted.mielczarek] 2007-06-10 09:26:55 PDT
Ok, so there are two separate issues here, both of which suck.  There's some sort of startup crash, and there's a Ts hit.  I'm not entirely surprised by a Ts hit, since the DLL loader probably has to parse the manifest out of every DLL now.  It'd be interesting to compare the effect on Firefox since it's a static build.  The crash is strange, I was able to reproduce it in a VM, and I submitted a crash report here:

It's crashing in nsFrame, but lower in the stack it looks like we're doing XPCOM shutdown.  I don't understand that.
Comment 54 Kai Engert (:kaie) (on vacation) 2007-07-13 14:33:36 PDT
With regards to NSPR, the patches from this bug are the only difference between HEAD and NSPRPUB_PRE_4_2_CLIENT_BRANCH (does not yet have the patch).

Note that we would like to obsolete the NSPRPUB_PRE_4_2_CLIENT_BRANCH, see bug 387992 and switch to snapshots of HEAD.

Is it ok for Mozilla trunk to pick up the changes from this bug, as checked in to NSPR HEAD?
Comment 55 Benjamin Smedberg [:bsmedberg] 2007-07-13 14:37:31 PDT
That should be fine. If it's not, the tinderbox will let us know ;-)
Comment 56 Ben Turner (not reading bugmail, use the needinfo flag!) 2007-08-03 17:28:02 PDT
I think this is wanted-1.9, right? Remove it if not.
Comment 57 Ben Turner (not reading bugmail, use the needinfo flag!) 2007-08-03 17:29:02 PDT
Actually, let's see if drivers feel that this is blocking-1.9.
Comment 58 Benjamin Smedberg [:bsmedberg] 2007-08-03 17:30:11 PDT
Well, I'd like for ted to try and reland it.
Comment 59 Ted Mielczarek [:ted.mielczarek] 2007-08-28 10:26:08 PDT
Comment on attachment 262548 [details] [diff] [review]
embed manifests in everything

Ok, I've rebuilt with this patch applied, and tested the resulting build on Vista and XPSP2 with no problems.  I'd like to check this back in.
Comment 60 Ted Mielczarek [:ted.mielczarek] 2007-08-28 10:38:37 PDT
Checked in.  Hopefully it sticks this time!
Comment 61 Robert Kaiser 2007-08-31 14:01:38 PDT
SeaMonkey Ts regressed again, like in comment #48 and comment #49 - I filed that as bug 350616 so that it's tracked.
I guess SeaMonkey will need to switch to libxul to fix that again, which is a target anyways.
Comment 62 Robert Kaiser 2007-08-31 15:16:09 PDT
Umm, sorry, wrong bug number. The Ts regression is bug 394470, actually.

Note You need to log in before you can comment on or make changes to this bug.