Bug 118567

Summary: [ATK] Leak: AtkRelationSet is not freed
Product: WebKit Reporter: Brian Holt <brian.holt>
Component: AccessibilityAssignee: Nobody <webkit-unassigned>
Status: UNCONFIRMED ---    
Severity: Normal CC: bugs-noreply, mario
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: Linux   
Bug Depends on:    
Bug Blocks: 116317    

Description Brian Holt 2013-07-11 08:28:38 PDT
In Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp

Leaks found using the "--leak" option in the Gtk port:

Command: /home/likewise-open/SERILOCAL/brian.holt/Code/gnome3/WebKit/WebKitBuild/Debug/Programs/DumpRenderTree -
Leak_DefinitelyLost
656 (32 direct, 624 indirect) bytes in 1 blocks are definitely lost in loss record 18,411 of 19,333
    malloc (/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    g_malloc (/WebKitBuild/Dependencies/Source/glib-2.36.0/glib/gmem.c:159)
    g_datalist_id_set_data_full (/WebKitBuild/Dependencies/Source/glib-2.36.0/glib/gdataset.c:468)
    g_object_weak_ref (/WebKitBuild/Dependencies/Source/glib-2.36.0/gobject/gobject.c:2519)
    atk_relation_set_property (/WebKitBuild/Dependencies/Source/atk-2.8.0/atk/atkrelation.c:468)
    g_object_newv (/WebKitBuild/Dependencies/Source/glib-2.36.0/gobject/gobject.c:1358)
    g_object_new_valist (/WebKitBuild/Dependencies/Source/glib-2.36.0/gobject/gobject.c:1836)
    g_object_new (/WebKitBuild/Dependencies/Source/glib-2.36.0/gobject/gobject.c:1551)
    atk_relation_new (/WebKitBuild/Dependencies/Source/atk-2.8.0/atk/atkrelation.c:254)
    atk_relation_set_add_relation_by_type (/WebKitBuild/Dependencies/Source/atk-2.8.0/atk/atkrelationset.c:336)
    setAtkRelationSetFromCoreObject(WebCore::AccessibilityObject*, _AtkRelationSet*) (/WebKitBuild/Debug/../../Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.cpp:207)
    webkitAccessibleRefRelationSet(_AtkObject*) (/WebKitBuild/Debug/../../Source/WebCore/accessibility/atk/WebKitAccessibleWrapperAtk.cpp:786)
    AccessibilityUIElement::titleUIElement() (/WebKitBuild/Debug/../../Tools/DumpRenderTree/atk/AccessibilityUIElementAtk.cpp:338)
    titleUIElementCallback(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) (/WebKitBuild/Debug/../../Tools/DumpRenderTree/AccessibilityUIElement.cpp:499)
    JSC::JSCallbackFunction::call(JSC::ExecState*) (/WebKitBuild/Debug/../../Source/JavaScriptCore/API/JSCallbackFunction.cpp:82)
    JSC::LLInt::handleHostCall(JSC::ExecState*, JSC::Instruction*, JSC::JSValue, JSC::CodeSpecializationKind) (/WebKitBuild/Debug/../../Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1334)
    JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) (/WebKitBuild/Debug/../../Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1378)
    JSC::LLInt::genericCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind) (/WebKitBuild/Debug/../../Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1434)
    llint_slow_path_call (/WebKitBuild/Debug/../../Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1440)
    0x59926D9 (/home/likewise-open/SERILOCAL/brian.holt/Code/gnome3/WebKit/WebKitBuild/Debug/.libs/libjavascriptcoregtk-3.0.so.0.14.2)
    JSC::JITCode::execute(JSC::JSStack*, JSC::ExecState*, JSC::VM*) (/WebKitBuild/Debug/../../Source/JavaScriptCore/jit/JITCode.h:135)
    JSC::Interpreter::execute(JSC::EvalExecutable*, JSC::ExecState*, JSC::JSValue, JSC::JSScope*) (/WebKitBuild/Debug/../../Source/JavaScriptCore/interpreter/Interpreter.cpp:1286)
    JSC::eval(JSC::ExecState*) (/WebKitBuild/Debug/../../Source/JavaScriptCore/interpreter/Interpreter.cpp:160)
    llint_slow_path_call_eval (/WebKitBuild/Debug/../../Source/JavaScriptCore/llint/LLIntSlowPaths.cpp:1489)
    0x59927D4 (/home/likewise-open/SERILOCAL/brian.holt/Code/gnome3/WebKit/WebKitBuild/Debug/.libs/libjavascriptcoregtk-3.0.so.0.14.2)
    JSC::JITCode::execute(JSC::JSStack*, JSC::ExecState*, JSC::VM*) (/WebKitBuild/Debug/../../Source/JavaScriptCore/jit/JITCode.h:135)
    JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) (/WebKitBuild/Debug/../../Source/JavaScriptCore/interpreter/Interpreter.cpp:937)
    JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, JSC::JSValue*) (/WebKitBuild/Debug/../../Source/JavaScriptCore/runtime/Completion.cpp:83)
    WebCore::JSMainThreadExecState::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, JSC::JSValue*) (/WebKitBuild/Debug/../../Source/WebCore/bindings/js/JSMainThreadExecState.h:77)
    WebCore::ScriptController::evaluateInWorld(WebCore::ScriptSourceCode const&, WebCore::DOMWrapperWorld*) (/WebKitBuild/Debug/../../Source/WebCore/bindings/js/ScriptController.cpp:142)
    WebCore::ScriptController::evaluate(WebCore::ScriptSourceCode const&) (/WebKitBuild/Debug/../../Source/WebCore/bindings/js/ScriptController.cpp:158)
    WebCore::ScriptElement::executeScript(WebCore::ScriptSourceCode const&) (/WebKitBuild/Debug/../../Source/WebCore/dom/ScriptElement.cpp:316)
    WebCore::ScriptElement::prepareScript(WTF::TextPosition const&, WebCore::ScriptElement::LegacyTypeSupport) (/WebKitBuild/Debug/../../Source/WebCore/dom/ScriptElement.cpp:245)
    WebCore::HTMLScriptRunner::runScript(WebCore::Element*, WTF::TextPosition const&) (/WebKitBuild/Debug/../../Source/WebCore/html/parser/HTMLScriptRunner.cpp:312)
    WebCore::HTMLScriptRunner::execute(WTF::PassRefPtr<WebCore::Element>, WTF::TextPosition const&) (/WebKitBuild/Debug/../../Source/WebCore/html/parser/HTMLScriptRunner.cpp:181)
    WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder() (/WebKitBuild/Debug/../../Source/WebCore/html/parser/HTMLDocumentParser.cpp:271)
    WebCore::HTMLDocumentParser::canTakeNextToken(WebCore::HTMLDocumentParser::SynchronousMode, WebCore::PumpSession&) (/WebKitBuild/Debug/../../Source/WebCore/html/parser/HTMLDocumentParser.cpp:290)
    WebCore::HTMLDocumentParser::pumpTokenizer(WebCore::HTMLDocumentParser::SynchronousMode) (/WebKitBuild/Debug/../../Source/WebCore/html/parser/HTMLDocumentParser.cpp:535)
    WebCore::HTMLDocumentParser::pumpTokenizerIfPossible(WebCore::HTMLDocumentParser::SynchronousMode) (/WebKitBuild/Debug/../../Source/WebCore/html/parser/HTMLDocumentParser.cpp:235)
    WebCore::HTMLDocumentParser::resumeParsingAfterScriptExecution() (/WebKitBuild/Debug/../../Source/WebCore/html/parser/HTMLDocumentParser.cpp:896)
Suppression (error hash=#0C61A705EC1048A6#):
  For more info on using suppressions see http://dev.chromium.org/developers/tree-sheriffs/sheriff-details-chromium/memory-sheriff#TOC-Suppressing-memory-reports
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   fun:malloc
   fun:g_malloc
   fun:g_datalist_id_set_data_full
   fun:g_object_weak_ref
   fun:atk_relation_set_property
   fun:g_object_newv
   fun:g_object_new_valist
   fun:g_object_new
   fun:atk_relation_new
   fun:atk_relation_set_add_relation_by_type
   fun:_ZL31setAtkRelationSetFromCoreObjectPN7WebCore19AccessibilityObjectEP15_AtkRelationSet
   fun:_ZL30webkitAccessibleRefRelationSetP10_AtkObject
   fun:_ZN22AccessibilityUIElement14titleUIElementEv
   fun:_ZL22titleUIElementCallbackPK15OpaqueJSContextP13OpaqueJSValueS3_mPKPKS2_PS5_
   fun:_ZN3JSC18JSCallbackFunction4callEPNS_9ExecStateE
   fun:_ZN3JSC5LLIntL14handleHostCallEPNS_9ExecStateEPNS_11InstructionENS_7JSValueENS_22CodeSpecializationKindE
   fun:_ZN3JSC5LLInt9setUpCallEPNS_9ExecStateEPNS_11InstructionENS_22CodeSpecializationKindENS_7JSValueEPNS_17LLIntCallLinkInfoE
   fun:_ZN3JSC5LLInt11genericCallEPNS_9ExecStateEPNS_11InstructionENS_22CodeSpecializationKindE
   fun:llint_slow_path_call
   obj:/home/likewise-open/SERILOCAL/brian.holt/Code/gnome3/WebKit/WebKitBuild/Debug/.libs/libjavascriptcoregtk-3.0.so.0.14.2
   fun:_ZN3JSC7JITCode7executeEPNS_7JSStackEPNS_9ExecStateEPNS_2VME
   fun:_ZN3JSC11Interpreter7executeEPNS_14EvalExecutableEPNS_9ExecStateENS_7JSValueEPNS_7JSScopeE
}
Comment 1 Brian Holt 2013-07-11 08:30:45 PDT
This seems to happen because the reference count of the target of the AtkRelation (an AtkObject) increases as result of caching.
Comment 2 Mario Sanchez Prada 2013-07-12 01:55:06 PDT
(In reply to comment #1)
> This seems to happen because the reference count of the target of the 
> AtkRelation (an AtkObject) increases as result of caching.

Yes, that is my guess as well. Since the memory allocated in this malloc happens because of being the first call to g_object_weak_ref() over that AtkRelation object (and not just because it should happen every time you call g_object_weark_ref()), that memory can't be released at the very same (future) moment when you call g_object_weak_unref(), since that might be causing problems.

Instead, that memory will be released when that AtkRelation object's ref count gets to zero, by means of the g_datalist_clear_data() function, which we double-checked it's what's will happen

So the point is why the object's ref_count is not getting down to zero, and I agree with Brian that probably is because of one cache retaining that object alive. Question is whether that cache is AXObjectCache, the cache in the Atk bridge or something else, and whether that's a problem (design issue in those caches?) or not.

Thus, let's keep this bug open since it will help remind us that there's something here, probably related to caches, that might require further investigation.