Closed
Bug 55139
Opened 24 years ago
Closed 24 years ago
save dialog only works once
Categories
(Core :: XPConnect, defect, P3)
Tracking
()
VERIFIED
FIXED
People
(Reporter: foxfx, Assigned: jband_mozilla)
References
Details
(Whiteboard: [rtm++])
Attachments
(3 files)
(deleted),
text/html
|
Details | |
(deleted),
patch
|
Details | Diff | Splinter Review | |
(deleted),
patch
|
Details | Diff | Splinter Review |
I can download a file once perfectly, but after the first download I can no
longer download any more files. The "action" dialog comes up, but when I select
"save" it just goes away and no save dialog appears.
Build is is 2000100215. OS distro is Mandrake 7.1
Asa (#mozillazine) has confirmed this bug as well with 100306 trunk linux build
on RedHat 6.2
Comment 1•24 years ago
|
||
by coicidence I was looking into this the other night as well.
Turns out it looks like an xpconnect problem which effects the file picker
component (which is implemented in JS).
jband is looking into the cause today...
Assignee: mscott → jband
Comment 2•24 years ago
|
||
Confirming for Asa, who told me he saw this today.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Assignee | ||
Comment 3•24 years ago
|
||
It turns out that the JS Component Loader is fouling up the JSObject parenting.
There are two main things wrong:
1) Before the fix to bug 52936 the loader was using the same JSContext
(of its own manufacture) regardless of thread. The fix there uses the thread
context stack to get a good context to run on. Unfortunately, it is trying
to 'peek' on the stack to find a current context before falling back on
getSafeContext. This is unfortunate because the stack could have a 'running'
context and when the loader calls JS_ExecuteScript it looks like a function call
to the engine and we end up linking in the scope of the frame on the JSContext
from the stack.
So, we would end up with some active window in the scope chain of the objects
created in the component. When that window later closes xpconnect's scheme for
finding *its* scope via a lookup of the Components object is whacked because the
closed window's global object has no more Components object and data conversion
in calls to the JS component fail with the infamous: "No 'Components' in scope!"
assertion.
My fix here is to use only getSafeContext and not try to peek on the stack at
all. By using getSafeContext we are assured of getting either: the JSContext of
the hidden window or a plain vanilla JSContext that xpconnect will make for us.
2) The loader's superglobal stuff was whacked. JSObjects in JS components were
getting the superglobal as their parent rather than the wrapped 'backstagepass'
global object that was intended. (shaver added this wrapped backstagepass object
as a way to extend security principals to scripts created in the scope of the
component). The parenting was not working as expected.
Having a Components object hanging off the superglobal was messy and the fact
that there was a shared component manager wrapper would cause wrong parenting of
any wrappers built through calls to that wrapped componenent manager.
My fix for this part is to just get rid of the superglobal. I use
nsIXPConnect::InitClassesWithNewWrappedGlobal instead. This allows us to have a
wrapped native as a global object without a superglobal. I changed it to wrap
the component manager once for each scope. The cost of that is not important.
This fixes the problem for me in my test case. nsSidebar continues to work also.
I'm going to attach a few items: a test case, a diagnostic patch, and the
proposed fix.
The test case...
Since this xp filepicker is being used on 'nix only and I prefer NT, I made a
page to launch the file picker from NT. The file picker is in
/xpfe/components/filepicker/src/nsFilePicker.js and is not copied to the
components directory by default on other platforms.
To run my test...
1) copy nsFilePicker.js to the components directory.
(the filename can be changed if you want)
2) change contractid in nsFilePicker.js (to avoid conflict)...
"@mozilla.org/filepicker;1"; -> "@mozilla.org/filepicker;2";
3) save the attached test html file to local file system (c:\temp\picker.html)
4) start browser and load file:///c|/temp/picker.html
(use file: url to avoid security hassles)
5) the picker should come up - it might not do this on first run after modifying
the JS component (this is another fun bug). Shutdown the browser and rerun if
the picker does not come up.
6) close the picker
7) open a new browser window (in the same process)
8) close the first window
9) load file:///c|/temp/picker.html
With the current build the picker will not launch in the second window after
closing the first, and you should see the no 'Components' in scope assertion.
If you apply the proposed fix to js/src/xpconnect/loader and rebuild there then
the test above should work and you should be able to run the picker over and
over again. The other cases where the unmodified picker does not run twice
should, of course, also be fixed.
The diagnostic patch...
I'm attaching a patch to xpconnect/src to add a debugger callable "DumpJSObject"
function. This can be called in MSDEV (at least) using a watch. You can inspect
a variable to get the JSObject* address (say 0x133f7f8) and then watch
"DumpJSObject((JSObject*)0x133f7f8)" If you set the 'current frame' in the
debugger's callstack window to a frame in the xpconnect module then the code
will dump to stdout something like the following. (this is like the stack dumper
explained in http://www.mozilla.org/scriptable/javascript-stack-dumper.html)
Debugging reminders...
class: (JSClass*)(obj->slots[2]-1)
parent: (JSObject*)(obj->slots[1])
proto: (JSObject*)(obj->slots[0])
0x133f7f8 'native' <Object>
parent: 0x1234550 'native' <global>
parent: 0x12331c8 'native' <Window>
parent: null
proto: 0x1233368 'native' <Object>
parent: 0x12331c8 'native' <Window> (SEE ABOVE)
proto: null
proto: 0x1233368 'native' <Object> (SEE ABOVE)
proto: 0x12345c0 'native' <Object>
parent: 0x1234550 'native' <global> (SEE ABOVE)
proto: 0x1233368 'native' <Object> (SEE ABOVE)
(The reminders are for me - I can never rememeber this stuff)
This gives address, 'native' or 'host', and object classname. It then shows the
parent and proto of the object. Objects previously seen say: (SEE ABOVE) and
don't list parent and proto.
...................................
For the real hardcore here are the parent and proto graphs before and after my
changes when loading the nsFilePicker.js component...
BEFORE...
notes: The superglobal is of classname "global"!
The wrapped backstagepass global is of classname XPCWrappedNativeWithCall
The 'window' is the current main window - not the hidden window.
Dump of the global object:
0x133f268 'native' <XPCWrappedNativeWithCall>
parent: null
proto: 0x1234550 'native' <global>
parent: 0x12331c8 'native' <Window>
parent: null
proto: 0x1233368 'native' <Object>
parent: 0x12331c8 'native' <Window> (SEE ABOVE)
proto: null
proto: 0x1233368 'native' <Object> (SEE ABOVE)
This is pretty reasonable. Except that we had no plan that the Window would be
the parent of the superglobal!
dump of the 'module' returned from NSGetModule() (a plain JSObject):
http://lxr.mozilla.org/seamonkey/source/xpfe/components/filepicker/src/nsFilePic
ker.js#183
0x133f7f8 'native' <Object>
parent: 0x1234550 'native' <global>
parent: 0x12331c8 'native' <Window>
parent: null
proto: 0x1233368 'native' <Object>
parent: 0x12331c8 'native' <Window> (SEE ABOVE)
proto: null
proto: 0x1233368 'native' <Object> (SEE ABOVE)
proto: 0x12345c0 'native' <Object>
parent: 0x1234550 'native' <global> (SEE ABOVE)
proto: 0x1233368 'native' <Object> (SEE ABOVE)
This is horked - the superglobal is the parent and its parent is the window!?!
The *real* global is nowhere to be found.
AFTER...
notes: No longer using superglobal.
'window' is hidden window.
Dump of the global object:
0x1346230 'native' <XPCWrappedNativeWithCall>
parent: null
proto: 0x1346278 'native' <Object>
parent: 0x1346230 'native' <XPCWrappedNativeWithCall> (SEE ABOVE)
proto: 0x116bcd8 'native' <Object>
parent: 0x116b720 'native' <Window>
parent: null
proto: 0x116bcd8 'native' <Object> (SEE ABOVE)
proto: null
looks ok to me.
dump of the 'module' returned from NSGetModule() (a plain JSObject):
0x1346ee8 'native' <Object>
parent: 0x1346230 'native' <XPCWrappedNativeWithCall>
parent: null
proto: 0x1346278 'native' <Object>
parent: 0x1346230 'native' <XPCWrappedNativeWithCall> (SEE ABOVE)
proto: 0x116bcd8 'native' <Object>
parent: 0x116b720 'native' <Window>
parent: null
proto: 0x116bcd8 'native' <Object> (SEE ABOVE)
proto: null
proto: 0x1346278 'native' <Object> (SEE ABOVE)
also looks good to me.
Also, I'll look for a bug on the 'first run' problem. We used to think this kind
of thing was mostly a matter of the component getting created early to do its
RegisterSelf and getting stuck with a non-DOM JSContext as the safeContext. In
my test case I'm seeing the problem that
"netscape.security.PrivilegeManager.enablePrivilege" silently fails because
(I think) the security manager got initialized too early and didn't properly
setup this namespace and so *no* DOM windows can process this call - it is not
even getting to really calling the JS component.
Anyway... I could stand some more testing of these patches. I'd like to get them
both in to at least the trunk sometime soon.
comments? reviews? approvals?
Thanks for reading!
John.
Status: NEW → ASSIGNED
Assignee | ||
Comment 4•24 years ago
|
||
Assignee | ||
Comment 5•24 years ago
|
||
Assignee | ||
Comment 6•24 years ago
|
||
Comment 7•24 years ago
|
||
adding the rtm keyword. PDT: because of this bug, you can only invoke the file
picker from the helper dialog ONCE per session. i.e. click on a link that
results in the helper app dialog coming up. Click on Save. The file picker asks
you for a location to save the file to.
Now try it again. the file picker doesn't come up.
jband, thanks so much for looking into this tonight. I'm trying your patch out
right now.
Keywords: rtm
Comment 8•24 years ago
|
||
your patch definetly fixes my problem. So far things are running good.
JSCLAutoContext::~JSCLAutoContext()
{
- if (mContext && mContextThread) {
- JS_EndRequest(mContext);
+ if (mContext) {
+ if (mContextThread) {
+ JS_EndRequest(mContext);
+ }
}
if (mPopNeeded) {
What's up with that change? Is it purely cosmetic (the file wasn't long enough
before?), or amy I missing some subtlety?
Other than that (and the use of ``glob'' to name a global: ``glob'' means
something else, especially in code that deals with file paths!), r=shaver and
thanks for the cleanup.
Assignee | ||
Comment 10•24 years ago
|
||
shaver, that change is an artifact of an experiment I did with having
JSCLAutoContext swap out the global object of the context from the stack:
@@ -1141,6 +1143,11 @@
if (mContextThread) {
JS_BeginRequest(mContext);
}
+ mGlobal = JS_GetGlobalObject(mContext);
+ if (mGlobal) {
+ JS_AddNamedRoot(mContext, &mGlobal, "JSCLAutoContext::mGlobal");
+ }
+ JS_SetGlobalObject(mContext, nsnull);
} else {
if (NS_SUCCEEDED(mError)) {
mError = NS_ERROR_FAILURE;
@@ -1150,8 +1157,14 @@
JSCLAutoContext::~JSCLAutoContext()
{
- if (mContext && mContextThread) {
- JS_EndRequest(mContext);
+ if (mContext) {
+ JS_SetGlobalObject(mContext, mGlobal);
+ if (mGlobal) {
+ JS_RemoveRoot(mContext, &mGlobal);
+ }
+ if (mContextThread) {
+ JS_EndRequest(mContext);
+ }
}
if (mPopNeeded) {
It turned out that the object apparently added to the scopechain was from cx->fp
and not cx->globalObject. I left in the insignificant change.
on glob: 'obj' was too generic and I was getting confused. js.c uses 'glob'.
Thanks.
Updated•24 years ago
|
Component: XP Apps → XPConnect
QA Contact: sairuh → pschwartau
Comment 11•24 years ago
|
||
over to xpconnect qa owner...
Comment 12•24 years ago
|
||
jband: a= on those patches, get shaver to give an r= by renaming glob to global
or some such. Thanks for fixing this. That DumpJSObject rules (there is also
printObj over in jsobj.c, #ifdef DEBUG, but it's old and pretty wimpy).
/be
Assignee | ||
Comment 13•24 years ago
|
||
I dealt with shaver's concerns and checked this into the trunk. What do I have
to do to get permission for the branch?
Comment 14•24 years ago
|
||
to get it in on the branch, we need to do a couple of things:
1) we need a manager to mark the bug rtm+
2) we need to list a sr= and r= in the bug report
3) ping PDT and they will turn it into a rtm++ assuming they agree with the
severity. If not, then I'm willing to go talk to them to try to convince 'em....
Comment 15•24 years ago
|
||
mscott: I gave a= (same as sr=, too many ways to abbreviate). shaver should
give an explicit r=, but he's already reviewed. I think we just need an [rtm+]
in the status whiteboard, which I'm taking the liberty of doing for warren.
/be
Whiteboard: [rtm+]
Comment 16•24 years ago
|
||
*** Bug 54967 has been marked as a duplicate of this bug. ***
Assignee | ||
Updated•24 years ago
|
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 18•24 years ago
|
||
fix checked into branch too.
Comment 19•24 years ago
|
||
Verified Fixed on WinNT, Linux, and Mac on trunk and branch.
Using 20001105xx trunk and commercial builds.
I used the test procedure John described above at 2000-10-04 00:30,
with one extra step: since release builds do not run component
AutoRegistration at startup, I had to delete the component.reg file
("Component Registry" on the Mac) to make that happen .
On Linux, where the XP filepicker runs by default, I simply invoked it
via File|Open File instead of of running the local testcase John created.
Status: RESOLVED → VERIFIED
You need to log in
before you can comment on or make changes to this bug.
Description
•