Closed Bug 387203 Opened 18 years ago Closed 18 years ago

getFolderContents() can crash [@nsNavHistoryContainerResultNode::CloseContainer] when JS GC happens

Categories

(Firefox :: Bookmarks & History, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
Firefox 3 beta1

People

(Reporter: moco, Assigned: moco)

References

Details

Attachments

(6 files, 8 obsolete files)

10.15 KB, text/plain
Details
11.55 KB, text/plain
Details
8.16 KB, patch
asaf
: review+
Details | Diff | Splinter Review
1.97 KB, text/plain
Details
14.86 KB, patch
sicking
: review+
Details | Diff | Splinter Review
3.31 KB, text/plain
Details
getFolderContents() can crash when JS GC happens with the patch in #378558 I am crashing when I attempt to copy the "root" bookmark in the left hand pane of the bookmark organizer. What I think is going is that JS GC is happening, and we are garbage collecting "result" [see getFolderContents()] getFolderContents: function PU_getFolderContents(aFolderId, aExcludeItems, aExpandQueries) { var query = this.history.getNewQuery(); query.setFolders([aFolderId], 1); var options = this.history.getNewQueryOptions(); options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1); options.excludeItems = aExcludeItems; options.expandQueries = aExpandQueries; var result = this.history.executeQuery(query, options); result.root.containerOpen = true; return asContainer(result.root); }, See attachment #1 [details] [diff] [review] for the stack to when we GC. Later, I'll crash in nsNavHistoryContainerResultNode::CloseContainer() because result points to freed memory. See attachment #2 [details] [diff] [review] for the stack Not, this is obviously not 100% reproducable, depending on when GC runs. (I think cyen didn't see it with a new profile, but did with an old one.) To fix this, in nsNavHistoryContainerResultNode, make mResult be a nsCOMPtr instead of a regular nsNavHistoryResult *. This way, mResult won't get collected until the node is no longer referenced. I'll attach a patch.
Attached patch patch to fix the crash (obsolete) — Splinter Review
Attachment #271318 - Flags: review?(dietrich)
this blocks cyen's bug, but crashes like this could be lurking in our code. (I'll check breakpad / bugzilla.)
Blocks: 378558
Status: NEW → ASSIGNED
Flags: blocking-firefox3?
Summary: getFolderContents() can crash when JS GC happens → getFolderContents() can crash [@nsNavHistoryContainerResultNode::CloseContainer] when JS GC happens
Target Milestone: --- → Firefox 3 beta1
Comment on attachment 271318 [details] [diff] [review] patch to fix the crash I think now I'm leaking nsNavHistoryResult and nsNavHistorQueryNode objects, as they own each other strongly. working on it...
Attachment #271318 - Attachment is obsolete: true
Attachment #271318 - Flags: review?(dietrich)
So we've a couple of issues here: 1) Nodes cannot live without their containing result being strong-ref'ed somewhere else (in the caller). 2) getFolderContents returns the root result node instead of the result itself. To fix 1) you'd need to keep a strong reference to the result in the root node of it, implement cycle-collection, ...and cross your fingers. We should fix 2) either way, I think.
working on both #1 and #2. FWIW, Jonas agrees about #1.
Attached patch patch, v1 (obsolete) — Splinter Review
Comment on attachment 271686 [details] [diff] [review] fix getFolderContents(), per mano r=mano
Attachment #271686 - Flags: review?(mano) → review+
getFolderContents() cleanup landed: Checking in places/content/controller.js; /cvsroot/mozilla/browser/components/places/content/controller.js,v <-- control ler.js new revision: 1.166; previous revision: 1.165 done Checking in places/content/places.js; /cvsroot/mozilla/browser/components/places/content/places.js,v <-- places.js new revision: 1.93; previous revision: 1.92 done Checking in places/content/utils.js; /cvsroot/mozilla/browser/components/places/content/utils.js,v <-- utils.js new revision: 1.48; previous revision: 1.47 done Checking in preferences/selectBookmark.js; /cvsroot/mozilla/browser/components/preferences/selectBookmark.js,v <-- select Bookmark.js new revision: 1.7; previous revision: 1.6 done
Running with my patch, there are scenarious where we traverse the cycles, unlink, and release the objects during cycle collection. But there are also some scenarios where we are leaking nsNavHistoryResult and nsNavHistoryContainerResultNode objects. I'm not sure if we've always been leaking those objects or not, but I'll investigate.
Attached patch updated patch (obsolete) — Splinter Review
Attachment #271614 - Attachment is obsolete: true
Comment on attachment 272069 [details] [diff] [review] updated patch seeking review for the crash fix. will spin off the leak issue into another bug.
Attachment #272069 - Flags: review?(mano)
Comment on attachment 272069 [details] [diff] [review] updated patch seeking additional review from Jonas.
Attachment #272069 - Flags: review?(jonas)
> will spin off the leak issue into another bug. I have not checked in yet, due to the leak issue. On simple startup / shutdown, there are new leaks are coming from the places toolbar and from exporting to bookmarks.html. (I'm not opening the history or bookmark menu) before: |<----------------Class--------------->|<-----Bytes------>|<----------------Objects---------------->|<--------------References-------------->| Per-Inst Leaked Total Rem Mean StdDev Total Rem Mean StdDev 0 TOTAL 29 201 256931 6 ( 1201.82 +/- 1707.26) 830208 5 ( 1191.39 +/- 1900.05) 62 StringAdopt 1 1 2559 1 ( 76.31 +/- 25.32) 0 0 ( 0.00 +/- 0.00) 443 nsLocalFile 88 176 2492 2 ( 270.45 +/- 152.13) 14008 2 ( 317.19 +/- 184.98) 567 nsStringBuffer 8 24 32624 3 ( 4693.88 +/- 2283.80) 59778 3 ( 5255.39 +/- 2489.45) after: |<----------------Class--------------->|<-----Bytes------>|<----------------Objects---------------->|<--------------References-------------->| Per-Inst Leaked Total Rem Mean StdDev Total Rem Mean StdDev 0 TOTAL 29 93233 275197 2490 ( 1210.31 +/- 1682.38) 897915 2491 ( 1267.67 +/- 1965.81) 465 nsNavHistoryContainerResultNode 144 5472 41 38 ( 22.23 +/- 12.43) 400 38 ( 32.13 +/- 12.46) 466 nsNavHistoryFolderResultNode 160 6080 39 38 ( 20.45 +/- 11.61) 374 38 ( 30.07 +/- 12.46) 467 nsNavHistoryQuery 112 224 11 2 ( 5.40 +/- 2.33) 66 2 ( 7.81 +/- 3.27) 468 nsNavHistoryQueryOptions 56 224 11 4 ( 6.17 +/- 2.62) 163 40 ( 23.40 +/- 14.89) 470 nsNavHistoryResult 144 288 5 2 ( 3.00 +/- 1.31) 167 38 ( 26.65 +/- 13.70) 471 nsNavHistoryResultNode 104 66976 647 644 ( 325.48 +/- 187.75) 4066 644 ( 461.51 +/- 209.92) 569 nsStringBuffer 8 13512 33858 1689 ( 4763.13 +/- 2227.65) 63377 1689 ( 5234.77 +/- 2453.19) 585 nsTArray_base 4 120 6412 30 ( 706.45 +/- 234.27) 0 0 ( 0.00 +/- 0.00) 631 nsVoidArray 4 160 9927 40 ( 2107.78 +/- 981.31) 0 0 ( 0.00 +/- 0.00) I'm investigating.
> I'm investigating. Sliding out of M7 to M8. Not a UI blocker, and I won't have time during M7 to track down this leak.
Target Milestone: Firefox 3 M7 → Firefox 3 M8
Comment on attachment 272069 [details] [diff] [review] updated patch let's see if we can figure out the leak by M8, then make the trade.
Attachment #272069 - Flags: review?(mano)
Flags: blocking-firefox3? → blocking-firefox3+
Target Milestone: Firefox 3 M8 → Firefox 3 M9
the leak might be fixed by bug #397221. I'll try again, as we need this.
using XPCOM_MEM_LEAK_LOG, make-tree.pl, find-leakers.pl, and fix-macosx-stack.pl (thanks dbaron!) to figure out why.
Attachment #272069 - Attachment is obsolete: true
Comment on attachment 284996 [details] [diff] [review] updated to trunk (for myk), still no progress on the leak >Index: src/nsNavHistoryResult.cpp >=================================================================== >+NS_IMPL_CYCLE_COLLECTION_0(nsNavHistoryResultNode) If you think these objects are part of a cycle then they must be holding a strong reference to something. This says they hold on to nothing, so they can't be part of a cycle.
Unless it's only used as baseclass for objects that do hold on to things.
Do you need to traverse mRootNode in nsNavHistoryResultNode?
> Do you need to traverse mRootNode in nsNavHistoryResultNode? that's not a member of nsNavHistoryResultNode, but of nsNavHistoryResult, and I'm already traversing it.
I think I have it! I need to traverse and unlink mChildren (in addition to mResult), in the cycle collector macros for nsNavHistoryContainerResultNode. triple checking now.
Heh, I'll just mid-aired trying to post this: Shouldn't you traverse mChildren in nsNavHistoryContainerResultNode? Note that the cycle collector won't collect a cycle unless it's aware of all the edges that hold nodes in that cycle.
Attached patch patch for review (obsolete) — Splinter Review
Attachment #285150 - Attachment is obsolete: true
Attachment #285152 - Flags: review?
Attachment #285152 - Flags: approval1.9?
Attachment #285152 - Flags: review? → review?(jonas)
Attached patch patch for review (obsolete) — Splinter Review
Attachment #285152 - Attachment is obsolete: true
Attachment #285154 - Flags: review?(jonas)
Attachment #285152 - Flags: review?(jonas)
Attachment #285152 - Flags: approval1.9?
Comment on attachment 285154 [details] [diff] [review] patch for review >-NS_INTERFACE_MAP_BEGIN(nsNavHistoryResult) >+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsNavHistoryResult) > NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsINavHistoryResult) > NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsNavHistoryResult) > NS_INTERFACE_MAP_ENTRY(nsINavHistoryResult) > NS_INTERFACE_MAP_ENTRY(nsINavBookmarkObserver) > NS_INTERFACE_MAP_ENTRY(nsINavHistoryObserver) > NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) >+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsNavHistoryResult) > NS_INTERFACE_MAP_END 180 #define NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(_class) \ 181 NS_INTERFACE_MAP_BEGIN(_class) \ 182 NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(_class) \ ...suggests the second change here is unnecessary.
thanks waldo.
Attachment #285154 - Attachment is obsolete: true
Attachment #285158 - Flags: review?(jonas)
Attachment #285154 - Flags: review?(jonas)
fixed Checking in nsNavBookmarks.cpp; /cvsroot/mozilla/toolkit/components/places/src/nsNavBookmarks.cpp,v <-- nsNavB ookmarks.cpp new revision: 1.123; previous revision: 1.122 done Checking in nsNavHistory.cpp; /cvsroot/mozilla/toolkit/components/places/src/nsNavHistory.cpp,v <-- nsNavHis tory.cpp new revision: 1.178; previous revision: 1.177 done Checking in nsNavHistoryResult.cpp; /cvsroot/mozilla/toolkit/components/places/src/nsNavHistoryResult.cpp,v <-- ns NavHistoryResult.cpp new revision: 1.119; previous revision: 1.118 done Checking in nsNavHistoryResult.h; /cvsroot/mozilla/toolkit/components/places/src/nsNavHistoryResult.h,v <-- nsNa vHistoryResult.h new revision: 1.48; previous revision: 1.47 done
Status: ASSIGNED → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Bug 451915 - move Firefox/Places bugs to Firefox/Bookmarks and History. Remove all bugspam from this move by filtering for the string "places-to-b-and-h". In Thunderbird 3.0b, you do that as follows: Tools | Message Filters Make sure the correct account is selected. Click "New" Conditions: Body contains places-to-b-and-h Change the action to "Delete Message". Select "Manually Run" from the dropdown at the top. Click OK. Select the filter in the list, make sure "Inbox" is selected at the bottom, and click "Run Now". This should delete all the bugspam. You can then delete the filter. Gerv
Component: Places → Bookmarks & History
QA Contact: places → bookmarks
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: