Closed
Bug 192478
Opened 22 years ago
Closed 22 years ago
mozilla freezes when 'View Selection Source' @ nsPipe3.cpp::nsPipeOutputStream::WriteSegments
Categories
(Core :: Networking, defect, P1)
Tracking
()
RESOLVED
FIXED
mozilla1.3final
People
(Reporter: gunnar.kaestle, Assigned: darin.moz)
References
()
Details
(Keywords: hang, Whiteboard: fixed1.3)
Attachments
(1 file)
|
1.49 KB,
patch
|
dougt
:
review+
bzbarsky
:
superreview+
dbaron
:
approval1.3+
|
Details | Diff | Splinter Review |
User-Agent: Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.3b) Gecko/20030201
Build Identifier: Mozilla/5.0 (X11; U; Linux i686; de-AT; rv:1.3b) Gecko/20030201
I found a document (using_priv_help.html), which freezes the Mozilla window when
asking for the sourcecode of a selected part.
Reproducible: Always
Steps to Reproduce:
1. Start Mozilla
2. Open URL as given above
3. Mark section 'Using the Cookie Manager ...
... and sends them back to the web site.'
4. Right-click and choose 'View Selection Source'
Actual Results:
Mozilla windows dont work, they are not addressable and display nothing.
Mozilla process has to be terminated.
Expected Results:
Show the source code of the selected section.
Comment 1•22 years ago
|
||
Confirming on Win2k with trunk build 2003020708.
OS -> All
Not sure about Component.
Status: UNCONFIRMED → NEW
Ever confirmed: true
OS: Linux → All
Comment 2•22 years ago
|
||
It's enough to highlight just the "r" in "Using the Cookie Manager" and the "A"
at the start of the next paragraph....
This is due to a bug in necko. View Selection Source does:
getBrowser().webNavigation
.loadURI("view-source:data:text/html;charset=utf-8," +
escape(tmpNode.innerHTML),
loadFlags, null, null, null);
and it is hanging when loadURI() is doing its work. Below is the precise spot
where the hang occurs, followed by the complete stack trace.
NS_IMETHODIMP
nsPipeOutputStream::WriteSegments(nsReadSegmentFun reader,
void* closure,
PRUint32 count,
PRUint32 *writeCount)
{
LOG(("OOO WriteSegments [this=%x count=%u]\n", this, count));
nsresult rv = NS_OK;
char *segment;
PRUint32 segmentLen;
*writeCount = 0;
while (count) {
rv = mPipe->GetWriteSegment(segment, segmentLen);
if (NS_FAILED(rv)) {
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
// pipe is full
if (!mBlocking) {
// ignore this error if we've already written something
if (*writeCount > 0)
rv = NS_OK;
break;
}
// wait for the pipe to have an empty segment.
HANG HERE>>>>>> rv = Wait(); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if (NS_SUCCEEDED(rv))
continue;
}
mPipe->OnPipeException(rv);
break;
}
// write no more than count
if (segmentLen > count)
segmentLen = count;
PRUint32 readCount, originalLen = segmentLen;
while (segmentLen) {
readCount = 0;
rv = reader(this, closure, segment, *writeCount, segmentLen,
&readCount);
if (NS_FAILED(rv) || (readCount == 0)) {
count = 0;
// any errors returned from the reader end here: do not
// propogate to the caller of WriteSegments.
rv = NS_OK;
break;
}
segment += readCount;
segmentLen -= readCount;
count -= readCount;
*writeCount += readCount;
mLogicalOffset += readCount;
}
if (segmentLen < originalLen)
mPipe->AdvanceWriteCursor(originalLen - segmentLen);
}
return rv;
}
STACK TRACE
===========
nsPipeOutputStream::WriteSegments(nsPipeOutputStream * const 0x03da99a0,
unsigned int (nsIOutputStream *, void *, char *, unsigned int, unsigned int,
unsigned int *)* 0x0523c390 nsReadData(nsIOutputStream *, void *, char *,
unsigned int, unsigned int, unsigned int *), void * 0x03da9bd0, unsigned int
36763, unsigned int * 0x0012c804) line 1029
nsDataChannel::ParseData() line 239 + 49 bytes
nsDataChannel::Init(nsIURI * 0x03df7fb0) line 82 + 8 bytes
nsDataHandler::NewChannel(nsDataHandler * const 0x03dc91f0, nsIURI * 0x03df7fb0,
nsIChannel * * 0x03df7c7c) line 127 + 12 bytes
nsIOService::NewChannelFromURI(nsIOService * const 0x00f7f2c8, nsIURI *
0x03df7fb0, nsIChannel * * 0x03df7c7c) line 460 + 40 bytes
nsIOService::NewChannel(nsIOService * const 0x00f7f2c8, const nsACString &
{...}, const char * 0x00000000, nsIURI * 0x00000000, nsIChannel * * 0x03df7c7c)
line 473 + 25 bytes
nsViewSourceChannel::Init(nsIURI * 0x03df7980) line 76 + 70 bytes
nsViewSourceHandler::NewChannel(nsViewSourceHandler * const 0x03d37f58, nsIURI *
0x03df7980, nsIChannel * * 0x0012cb18) line 124 + 12 bytes
nsIOService::NewChannelFromURI(nsIOService * const 0x00f7f2c8, nsIURI *
0x03df7980, nsIChannel * * 0x0012cb18) line 460 + 40 bytes
NS_NewChannel(nsIChannel * * 0x0012cc34, nsIURI * 0x03df7980, nsIIOService *
0x00f7f2c8, nsILoadGroup * 0x03c35320, nsIInterfaceRequestor * 0x03bff758,
unsigned int 524288) line 163 + 20 bytes
nsDocShell::DoURILoad(nsIURI * 0x03df7980, nsIURI * 0x00000000, nsISupports *
0x03c3c238, nsIInputStream * 0x00000000, nsIInputStream * 0x00000000, int 1,
nsIDocShell * * 0x00000000, nsIRequest * * 0x00000000) line 5233 + 91 bytes
nsDocShell::InternalLoad(nsDocShell * const 0x03bff730, nsIURI * 0x03df7980,
nsIURI * 0x00000000, nsISupports * 0x00000000, int 1, const unsigned short *
0x03cd5330, nsIInputStream * 0x00000000, nsIInputStream * 0x00000000, unsigned
int 1, nsISHEntry * 0x00000000, int 1, nsIDocShell * * 0x00000000, nsIRequest *
* 0x00000000) line 5147 + 51 bytes
nsDocShell::LoadURI(nsDocShell * const 0x03bff730, nsIURI * 0x03df7980,
nsIDocShellLoadInfo * 0x03df79e8, unsigned int 0, int 1) line 725 + 80 bytes
nsDocShell::LoadURI(nsDocShell * const 0x03bff740, const unsigned short *
0x04230068, unsigned int 256, nsIURI * 0x00000000, nsIInputStream * 0x00000000,
nsIInputStream * 0x00000000) line 2450 + 41 bytes
XPTC_InvokeByIndex(nsISupports * 0x03bff740, unsigned int 8, unsigned int 5,
nsXPTCVariant * 0x0012d370) line 102
XPCWrappedNative::CallMethod(XPCCallContext & {...}, XPCWrappedNative::CallMode
CALL_METHOD) line 2023 + 42 bytes
XPC_WN_CallMethod(JSContext * 0x039cece0, JSObject * 0x03c01ef8, unsigned int 5,
long * 0x03c631ac, long * 0x0012d64c) line 1292 + 14 bytes
js_Invoke(JSContext * 0x039cece0, unsigned int 5, unsigned int 0) line 839 + 23
bytes
js_Interpret(JSContext * 0x039cece0, long * 0x0012e494) line 2803 + 15 bytes
js_Invoke(JSContext * 0x039cece0, unsigned int 1, unsigned int 2) line 856 + 13
bytes
js_InternalInvoke(JSContext * 0x039cece0, JSObject * 0x033ce790, long 60499184,
unsigned int 0, unsigned int 1, long * 0x0012e6f0, long * 0x0012e5c0) line 931 +
20 bytes
JS_CallFunctionValue(JSContext * 0x039cece0, JSObject * 0x033ce790, long
60499184, unsigned int 1, long * 0x0012e6f0, long * 0x0012e5c0) line 3431 + 31 bytes
nsJSContext::CallEventHandler(nsJSContext * const 0x038606f8, void * 0x033ce790,
void * 0x039b24f0, unsigned int 1, void * 0x0012e6f0, int * 0x0012e6f4, int 0)
line 1040 + 33 bytes
nsJSEventListener::HandleEvent(nsJSEventListener * const 0x0390d9b8, nsIDOMEvent
* 0x03c3caf8) line 181 + 77 bytes
nsEventListenerManager::HandleEventSubType(nsListenerStruct * 0x0390da78,
nsIDOMEvent * 0x03c3caf8, nsIDOMEventTarget * 0x039f71e0, unsigned int 1,
unsigned int 7) line 1216 + 20 bytes
nsEventListenerManager::HandleEvent(nsEventListenerManager * const 0x038858e0,
nsIPresContext * 0x03882f00, nsEvent * 0x0012ee2c, nsIDOMEvent * * 0x0012ede8,
nsIDOMEventTarget * 0x039f71e0, unsigned int 7, nsEventStatus * 0x0012ee54) line
1898 + 36 bytes
GlobalWindowImpl::HandleDOMEvent(GlobalWindowImpl * const 0x039f71d0,
nsIPresContext * 0x03882f00, nsEvent * 0x0012ee2c, nsIDOMEvent * * 0x0012ede8,
unsigned int 7, nsEventStatus * 0x0012ee54) line 805
DocumentViewerImpl::LoadComplete(DocumentViewerImpl * const 0x03891400, unsigned
int 0) line 936 + 47 bytes
nsDocShell::EndPageLoad(nsIWebProgress * 0x03afc804, nsIChannel * 0x03ac63e8,
unsigned int 0) line 4278
nsWebShell::EndPageLoad(nsIWebProgress * 0x03afc804, nsIChannel * 0x03ac63e8,
unsigned int 0) line 774
nsDocShell::OnStateChange(nsDocShell * const 0x03afc67c, nsIWebProgress *
0x03afc804, nsIRequest * 0x03ac63e8, unsigned int 131088, unsigned int 0) line 4210
nsDocLoaderImpl::FireOnStateChange(nsIWebProgress * 0x03afc804, nsIRequest *
0x03ac63e8, int 131088, unsigned int 0) line 1230
nsDocLoaderImpl::doStopDocumentLoad(nsIRequest * 0x03ac63e8, unsigned int 0)
line 867
nsDocLoaderImpl::DocLoaderIsEmpty() line 765
nsDocLoaderImpl::DocLoaderIsEmpty() line 768
nsDocLoaderImpl::OnStopRequest(nsDocLoaderImpl * const 0x03c350dc, nsIRequest *
0x03c35868, nsISupports * 0x00000000, unsigned int 0) line 695
nsLoadGroup::RemoveRequest(nsLoadGroup * const 0x03c35320, nsIRequest *
0x03c35868, nsISupports * 0x00000000, unsigned int 0) line 694 + 35 bytes
nsInputStreamChannel::OnStopRequest(nsInputStreamChannel * const 0x03c3586c,
nsIRequest * 0x03c35980, nsISupports * 0x00000000, unsigned int 0) line 357
nsInputStreamPump::OnStateStop() line 462
nsInputStreamPump::OnInputStreamReady(nsInputStreamPump * const 0x03c35984,
nsIAsyncInputStream * 0x03c35a6c) line 320 + 11 bytes
nsInputStreamReadyEvent::EventHandler(PLEvent * 0x039dcfb4) line 102
PL_HandleEvent(PLEvent * 0x039dcfb4) line 663 + 10 bytes
PL_ProcessPendingEvents(PLEventQueue * 0x00f33e20) line 593 + 9 bytes
nsEventQueueImpl::ProcessPendingEvents(nsEventQueueImpl * const 0x00ef93b0) line
387 + 12 bytes
nsWindow::DispatchPendingEvents() line 3729
nsWindow::ProcessMessage(unsigned int 512, unsigned int 0, long 15270082, long *
0x0012fc38) line 4072
nsWindow::WindowProc(HWND__ * 0x00a003d4, unsigned int 512, unsigned int 0, long
15270082) line 1402 + 27 bytes
USER32! 77e148dc()
USER32! 77e14aa7()
USER32! 77e14bf7()
nsAppShellService::Run(nsAppShellService * const 0x0157a718) line 480
main1(int 1, char * * 0x00270060, nsISupports * 0x00ef5468) line 1273 + 32 bytes
main(int 1, char * * 0x00270060) line 1636 + 37 bytes
mainCRTStartup() line 338 + 17 bytes
KERNEL32! 77e992a6()
BTW, to debug this, I just added a break point and stepped in the debugger:
===========================================================================
NS_IMETHODIMP
nsDocShell::LoadURI(const PRUnichar * aURI,
PRUint32 aLoadFlags,
nsIURI * aReferingURI,
nsIInputStream * aPostStream,
nsIInputStream * aHeaderStream)
{
nsAutoString tmp(aURI);
if (tmp.Find(NS_LITERAL_STRING("view-source:data")) >= 0)
NS_ASSERTION(0,"XXXrbs break - nsDocShell::LoadURI");
[...]
}
Comment 5•22 years ago
|
||
darin?
Helpful short-cut to save debugging time: assuming you select 'r' and 'A'
(comment 2) and View Selection Source with that, you can quickly leap-frog to
where/when the hang occurs, by just adding this break-point in
nsPipeOutputStream::WriteSegments() in xpcom\io\nsPipe3.cpp:
*writeCount = 0;
while (count) {
if (count == 36763) NS_ASSERTION(0, "will hang");
[...]
}
Bug 161511 shares some similarities with this one, with the top of the stack
traces all pointing at nsPipe::nsPipeInputStream::ReadSegments().
Maybe this bug is going to shed some light into what is happening.
-> necko
Assignee: rbs → darin
Component: ViewSource → Networking
Summary: mozilla freezes when 'View Selection Source' → mozilla freezes when 'View Selection Source' @ nsPipe3.cpp::nsPipeOutputStream::WriteSegments
Comment 9•22 years ago
|
||
I have similar symptoms at:
http://www.hyperorg.com/backissues/joho-feb14-03.html#class
if I highlight from "Individuality, Society and Self: ..." to "... is a really
good book. Wish I had read it sooner.)" and View Selection Source, it locks up.
This happened with Windows 98 and 2000 Mozilla 1.3b.
Comment 10•22 years ago
|
||
Here's what's going on:
1) The data: channel instantiates a pipe using NS_NewPipe with no params. This
means blocking input, blocking output, default maximum size (which happens to
be 4096*16 == 65536 bytes).
2) The data channel writes all the data for the data: url to this pipe. For the
case we're looking at that's 97880 bytes when I tried it. (Selection across
two kids of <body> means we're serializing the source of the whole page into
that data: url)
3) Since the pipe is blocking, it blocks when there are 97880 - 65536 == 32344
bytes left to write.
So now we've blocked on the UI thread. Since no one is reading from the input
end of the pipe yet, we're blocked _permanently_ on the UI thread. Congrats, a
hang. ;)
One simple fix would be to just make the pipe be a max size of PR_UINT32_MAX
instead of the default max size.
Another simple fix would be that blocking pipes should default to the max
possible size instead of 65536 bytes.
In addition to any or both of those, we should also think about possible ways to
not move these huge gobs of data about in the data: channel....
Updated•22 years ago
|
QA Contact: pmac → benc
Updated•22 years ago
|
Flags: blocking1.3?
Flags: blocking1.3? → blocking1.3+
| Assignee | ||
Updated•22 years ago
|
Status: NEW → ASSIGNED
Priority: -- → P1
Target Milestone: --- → mozilla1.3final
| Assignee | ||
Comment 11•22 years ago
|
||
hmm... so, this appears as a regression since the default pipe size used to be
1MB, and is now only 64k. the data channel should use an unbounded pipe.
| Assignee | ||
Comment 12•22 years ago
|
||
make data channel use an unbounded pipe w/ necko's recycling allocator.
| Assignee | ||
Updated•22 years ago
|
Attachment #114605 -
Flags: superreview?(bzbarsky)
Attachment #114605 -
Flags: review?(dougt)
Comment 13•22 years ago
|
||
Comment on attachment 114605 [details] [diff] [review]
v1 patch
OK, that works.
Attachment #114605 -
Flags: superreview?(bzbarsky) → superreview+
| Assignee | ||
Comment 14•22 years ago
|
||
bz: i went with the "simpler" solution because really, pipes are intended to
have a limited size. there is usually a reader and a writer. so, it makes
sense to keep the default limits bounded at something reasonable.
Updated•22 years ago
|
Attachment #114605 -
Flags: review?(dougt) → review+
| Assignee | ||
Updated•22 years ago
|
Attachment #114605 -
Flags: approval1.3?
Comment 15•22 years ago
|
||
Yeah, makes sense. I stand by my earlier "we should try to make nsDataChannel
not suck so much" suggestion, though... Do we have a streaming base64 decoder we
could use instead of what we do now? If so, we may be able to switch to
decoding and delivering the data in byte-size chunks on request.....
Attachment #114605 -
Flags: approval1.3? → approval1.3+
| Assignee | ||
Comment 16•22 years ago
|
||
bz: no, i don't think we have a streaming base64 decoder... though i wonder if
mailnews doesn't have one.
| Assignee | ||
Comment 17•22 years ago
|
||
fixed-on-trunk
Status: ASSIGNED → RESOLVED
Closed: 22 years ago
Resolution: --- → FIXED
Comment 18•22 years ago
|
||
did this break os/2?
Comment 19•22 years ago
|
||
I would think that just encoding chunks of data with PL_Base64Encode or what
that's called, and later decoding them again, would work ok...
Comment 20•22 years ago
|
||
It's decoding, and doesn't base64 use multibyte sequences that could cross
buffer boundaries?
Comment 21•22 years ago
|
||
if you always read multiples of 4 bytes, you should be ok, because 3 source
bytes get encoded to 4 encoded bytes.
Comment 22•22 years ago
|
||
Wanna write a patch? ;)
Updated•22 years ago
|
Whiteboard: fixed1.3
Comment 23•22 years ago
|
||
while that would help for b64 data, it would not help for textual data, which is
also written as a single block of data into the pipe.
You need to log in
before you can comment on or make changes to this bug.
Description
•