Created attachment 179845 [details] Sample file This was originally reported on the dev mailing list, s. thread starting at https://lists.freedesktop.org/archives/libreoffice/2022-April/088794.html Steps to reproduce: 1) open attached document "test.xlsx" in Android Viewer 2) scroll down the document, then up again 3) repeat step 2 over and over again Actual result: At some point in time (in my case, I usually had to repeat step 2 about 2-10 times, depending on the device), the app crashes because it runs out of memory. This is with git master as of commit 6c724e18c2af227c2ad865342531ff35b0d511ac.
In a memory profile created with perfetto's "heap_profile" tool, the xdictionary ctor clearly showed up as allocating memory that was not freed, easily more than 1GB after a while. For the Chinese sample doc, it get's called when painting a tile with this backtrace: > i18npool::xdictionary::xdictionary(char const*) xdictionary.cxx:69 > std::__ndk1::__unique_if<i18npool::xdictionary>::__unique_single std::__ndk1::make_unique<i18npool::xdictionary, char const (&) [3]>(char const (&) [3]) memory:3132 > i18npool::BreakIterator_zh::BreakIterator_zh() breakiterator_cjk.cxx:147 > ::i18npool_BreakIterator_zh_get_implementation(com::sun::star::uno::XComponentContext *, const com::sun::star::uno::Sequence<com::sun::star::uno::Any> &) registerservices.cxx:242 > decltype(std::__ndk1::forward<com::sun::star::uno::XInterface* (*&)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&)>(fp)(std::__ndk1::forward<com::sun::star::uno::XComponentContext*>(fp0), std::__ndk1::forward<com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&>(fp0))) std::__ndk1::__invoke<com::sun::star::uno::XInterface* (*&)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&), com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&>(com::sun::star::uno::XInterface* (*&)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&), com::sun::star::uno::XComponentContext*&&, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&) type_traits:4353 > com::sun::star::uno::XInterface* std::__ndk1::__invoke_void_return_wrapper<com::sun::star::uno::XInterface*>::__call<com::sun::star::uno::XInterface* (*&)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&), com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&>(com::sun::star::uno::XInterface* (*&)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&), com::sun::star::uno::XComponentContext*&&, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&) __functional_base:318 > std::__ndk1::__function::__alloc_func<com::sun::star::uno::XInterface* (*)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&), std::__ndk1::allocator<com::sun::star::uno::XInterface* (*)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&)>, com::sun::star::uno::XInterface* (com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&)>::operator()(com::sun::star::uno::XComponentContext*&&, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&) functional:1527 > std::__ndk1::__function::__func<com::sun::star::uno::XInterface* (*)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&), std::__ndk1::allocator<com::sun::star::uno::XInterface* (*)(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&)>, com::sun::star::uno::XInterface* (com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&)>::operator()(com::sun::star::uno::XComponentContext*&&, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&) functional:1651 > std::__ndk1::__function::__value_func<com::sun::star::uno::XInterface* (com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&)>::operator()(com::sun::star::uno::XComponentContext*&&, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&) const functional:1799 > std::__ndk1::function<com::sun::star::uno::XInterface* (com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&)>::operator()(com::sun::star::uno::XComponentContext*, com::sun::star::uno::Sequence<com::sun::star::uno::Any> const&) const functional:2347 > cppuhelper::ServiceManager::Data::Implementation::doCreateInstance(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&) servicemanager.cxx:705 > cppuhelper::ServiceManager::Data::Implementation::createInstance(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&, bool) servicemanager.cxx:674 > cppuhelper::ServiceManager::createInstanceWithContext(rtl::OUString const&, com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&) servicemanager.cxx:1005 > non-virtual thunk to cppuhelper::ServiceManager::createInstanceWithContext(rtl::OUString const&, com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const&) servicemanager.cxx:0 > i18npool::BreakIteratorImpl::createLocaleSpecificBreakIterator(rtl::OUString const&) breakiteratorImpl.cxx:596 > i18npool::BreakIteratorImpl::getLocaleSpecificBreakIterator(com::sun::star::lang::Locale const&) breakiteratorImpl.cxx:647 > i18npool::BreakIteratorImpl::nextWord(rtl::OUString const&, int, com::sun::star::lang::Locale const&, short) breakiteratorImpl.cxx:147 > non-virtual thunk to i18npool::BreakIteratorImpl::nextWord(rtl::OUString const&, int, com::sun::star::lang::Locale const&, short) breakiteratorImpl.cxx:0 > ImpEditEngine::WordRight(EditPaM const&, short) impedit2.cxx:1504 > ImpEditEngine::DoOnlineSpelling(ContentNode*, bool, bool) impedit4.cxx:2307 > EditEngine::CompleteOnlineSpelling() editeng.cxx:2393 > sc::SpellCheckContext::ensureResults(short, int) spellcheckcontext.cxx:339 > sc::SpellCheckContext::isMisspelled(short, int) const spellcheckcontext.cxx:219 > ScOutputData::LayoutStrings(bool, bool, ScAddress const&) output2.cxx:1633 > ScOutputData::DrawStrings(bool) output2.cxx:1470 > ScGridWindow::DrawContent(OutputDevice&, ScTableInfo const&, ScOutputData&, bool) gridwin4.cxx:920 > ScGridWindow::PaintTile(VirtualDevice&, int, int, int, int, long, long) gridwin4.cxx:1627 > ScModelObj::paintTile(VirtualDevice&, int, int, int, int, long, long) docuno.cxx:559 > non-virtual thunk to ScModelObj::paintTile(VirtualDevice&, int, int, int, int, long, long) docuno.cxx:0 > doc_paintTile(_LibreOfficeKitDocument*, unsigned char*, int, int, int, int, int, int) init.cxx:3478 > ::Java_org_libreoffice_kit_Document_paintTileNative(JNIEnv *, jobject, jobject, jint, jint, jint, jint, jint, jint) lokandroid.cxx:267 > art_quick_generic_jni_trampoline 0x000070fb4d19ffac > art_quick_invoke_stub 0x000070fb4d194c95 > art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) 0x000070fb4d21d67b > art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*) 0x000070fb4d3a2c9d > bool art::interpreter::DoCall<true, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x000070fb4d39dfc7 > void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x000070fb4d1abfe6 > ExecuteSwitchImplAsm 0x000070fb4d1a2056 > art::interpreter::ExecuteSwitch(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool) 0x000070fb4d39c3ae > art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) 0x000070fb4d394421 > art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x000070fb4d39be9c > bool art::interpreter::DoCall<true, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x000070fb4d39dfaf > void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x000070fb4d1acf96 > ExecuteSwitchImplAsm 0x000070fb4d1a2056 > art::interpreter::ExecuteSwitch(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool) 0x000070fb4d39c3ae > art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) 0x000070fb4d394421 > art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x000070fb4d39be9c > bool art::interpreter::DoCall<true, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x000070fb4d39dfaf > void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x000070fb4d1acf96 > ExecuteSwitchImplAsm 0x000070fb4d1a2056 > art::interpreter::ExecuteSwitch(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool) 0x000070fb4d39c3ae > art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) 0x000070fb4d394421 > art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x000070fb4d39be9c > bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x000070fb4d39ca8e > void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x000070fb4d1ad330 > ExecuteSwitchImplAsm 0x000070fb4d1a2056 > art::interpreter::ExecuteSwitch(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool) 0x000070fb4d39c3ae > art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) 0x000070fb4d394421 > art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x000070fb4d39be9c > bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x000070fb4d39ca8e > void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x000070fb4d1abe50 > ExecuteSwitchImplAsm 0x000070fb4d1a2056 > art::interpreter::ExecuteSwitch(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool) 0x000070fb4d39c3ae > art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) 0x000070fb4d394421 > art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*) 0x000070fb4d39be9c > bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*) 0x000070fb4d39ca8e > void art::interpreter::ExecuteSwitchImplCpp<false, false>(art::interpreter::SwitchImplContext*) 0x000070fb4d1abe50 > ExecuteSwitchImplAsm 0x000070fb4d1a2056 > art::interpreter::ExecuteSwitch(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool) 0x000070fb4d39c3ae > art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) 0x000070fb4d394421 > artQuickToInterpreterBridge 0x000070fb4d758b40 > art_quick_to_interpreter_bridge 0x000070fb4d1a013d > art_quick_invoke_stub 0x000070fb4d194c95 > art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*) 0x000070fb4d21d67b > art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*) 0x000070fb4d619e2f > art::Thread::CreateCallback(void*) 0x000070fb4d679420 > __pthread_start(void*) 0x000070fe0146e58b > __start_thread 0x000070fe01406d88 >
(In reply to Michael Weghorn from comment #0) > Created attachment 179845 [details] > Steps to reproduce: > > 1) open attached document "test.xlsx" in Android Viewer > 2) scroll down the document, then up again > 3) repeat step 2 over and over again Note that switching to the first tab in the sheet makes this easier to reproduce, that one has more rows.
Michael Weghorn committed a patch related to this issue. It has been pushed to "master": https://git.libreoffice.org/core/commit/d4370761421508522a29c5206aea6e538d71b342 tdf#148851 Unmap + close file again in xdictionary dtor It will be available in 7.4.0. The patch should be included in the daily builds available at https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More information about daily builds can be found at: https://wiki.documentfoundation.org/Testing_Daily_Builds Affected users are encouraged to test the fix and report feedback.
With the commit from comment 3 in place, I didn't see any more crashes or unexpected memory usage increase when testing more with the sample doc and experimental mode *disabled*. I can still reproduce a crash due to running out of memory with experimental mode *enabled*, though, which has a different root cause. I have created a separate ticket to keep track of that: tdf#148854