New issue
Advanced search Search tips

Issue 775994 link

Starred by 2 users

Issue metadata

Status: Untriaged
Owner: ----
Cc:
EstimatedDays: ----
NextAction: ----
OS: Android
Pri: 3
Type: Bug

Blocked on:
issue 766752



Sign in to add a comment

"heap corruption detected" crashes

Project Member Reported by dskiba@chromium.org, Oct 18 2017

Issue description

dlmalloc has a nice feature of detecting double frees and aborting the app in that case. While dlmalloc is not used in recent Android versions (since M, or since N for low-end), we still get crash reports from old Android versions.

When dlmalloc aborts the app it prints "heap corruption detected by dlfree" to the logcat, and thanks to our logcat parsing we can find *some* of the crashes:

https://crash.corp.google.com/browse?q=product.name%3D%27Chrome_Android%27%20AND%20crash.Reason%3D%27SIGABRT%27%20OMIT%20RECORD%20IF%20SUM(special_protos.android_info.logcat_errors%20LIKE%20%27%25heap%20corruption%20detected%25%27)%20%3D%200&sql_dialect=dremelsql&ignore_case=false&enable_rewrite=false&omit_field_name=&omit_field_value=&omit_field_opt=&stbtiq=&reportid=&index=0

That's ~430K reports total.

Note that I said *some* - it's because only we preserve only 10 latest logcat errors, and sometimes that doesn't include "heap corruption" message.

Let's make this issue an umbrella bug for all heap corruption issues on Android.

If we end up with many issues here, the next logical step would be to implement heap integrity detection in Chrome itself.
 

Comment 1 Deleted

Comment 2 by dskiba@chromium.org, Oct 18 2017

Blockedon: 766752

Comment 3 Deleted

Comment 4 Deleted

Comment 5 by dskiba@chromium.org, Oct 18 2017

Blockedon: 775874

Comment 6 by dskiba@chromium.org, Oct 18 2017

Blockedon: -775874

Comment 7 by dskiba@chromium.org, Oct 19 2017

Description: Show this description

Comment 8 by dskiba@chromium.org, Oct 19 2017

280 crashes in 63.* builds: https://crash.corp.google.com/browse?q=product.name%3D%27Chrome_Android%27%20AND%20product.Version%20LIKE%20%2763%25%27%20AND%20crash.Reason%3D%27SIGABRT%27%20OMIT%20RECORD%20IF%20SUM(special_protos.android_info.logcat_errors%20LIKE%20%27%25heap%20corruption%20detected%25%27)%20%3D%200&sql_dialect=dremelsql&ignore_case=false&enable_rewrite=false&omit_field_name=&omit_field_value=&omit_field_opt=&stbtiq=&reportid=&index=0


What is interesting is that there are 49 reports that have "heap corruption detected" message, but they are not SIGABRTs. Looks like some of them are legitimate, because on some version of Android abort() was implemented as a write to 0xdeadbaad.

Cc: bcwh...@chromium.org boliu@chromium.org torne@chromium.org
+Folks who might find this interesting.
Cc: tzik@chromium.org
There are 85 reports in 63.* (excluding crashes fixed by issue 766752) that have BindState::Destroy: https://crash.corp.google.com/browse?q=product.name%3D%27Chrome_Android%27%20AND%20product.Version%20LIKE%20%2763%25%27%20AND%20crash.Reason%3D%27SIGABRT%27%20OMIT%20RECORD%20IF%20SUM(special_protos.android_info.logcat_errors%20LIKE%20%27%25heap%20corruption%20detected%25%27)%20%3D%200%20OR%20SUM(CrashedStackTrace.StackFrame.FunctionName%20LIKE%20%27CookiesTreeModel%25%27)%20!%3D%200%20OR%20SUM(CrashedStackTrace.StackFrame.FunctionName%20LIKE%20%27%25BindState%25%3A%3ADestroy%25%27)%20%3D%200&sql_dialect=dremelsql&ignore_case=false&enable_rewrite=false&omit_field_name=&omit_field_value=&omit_field_opt=#samplereports

I.e. in all those crashes BindState::Destroy() caused double free. Any idea how it can happen? As I understand either BindState owns something, or it doesn't delete it during destruction.

Some stacks:

<ref_counted.h:409, name omitted>
base::internal::BindState<void ((anonymous namespace)::AndroidAccessTokenFetcher::*)(GoogleServiceAuthError const&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, base::Time const&), base::WeakPtr<(anonymous namespace)::AndroidAccessTokenFetcher> >::Destroy(base::internal::BindStateBase const*)
base::internal::CallbackBase::~CallbackBase()
base::OnceCallback<void (GURL const&)>::Run(GURL const&) &&
base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*)
base::MessageLoop::RunTask(base::PendingTask*)
base::MessageLoop::DoWork()
Java_org_chromium_base_SystemMessageHandler_nativeDoRunLoopOnce


<ref_counted.h:409, name omitted>
base::internal::BindState<void ((anonymous namespace)::AndroidAccessTokenFetcher::*)(GoogleServiceAuthError const&, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> > const&, base::Time const&), base::WeakPtr<(anonymous namespace)::AndroidAccessTokenFetcher> >::Destroy(base::internal::BindStateBase const*)
base::internal::CallbackBase::~CallbackBase()
base::OnceCallback<void (GURL const&)>::Run(GURL const&) &&
void base::internal::FunctorTraits<base::RepeatingCallback<void (scoped_refptr<content::AppCacheInfoCollection>)>, void>::Invoke<base::RepeatingCallback<void (scoped_refptr<content::AppCacheInfoCollection>)>, scoped_refptr<content::AppCacheInfoCollection> >(base::RepeatingCallback<void (scoped_refptr<content::AppCacheInfoCollection>)>&&, scoped_refptr<content::AppCacheInfoCollection>&&)
base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*)
base::MessageLoop::RunTask(base::PendingTask*)
base::MessageLoop::DoWork()
Java_org_chromium_base_SystemMessageHandler_nativeDoRunLoopOnce


<memory:1636, name omitted>
std::__ndk1::__list_imp<BrowsingDataLocalStorageHelper::LocalStorageInfo, std::__ndk1::allocator<BrowsingDataLocalStorageHelper::LocalStorageInfo> >::clear()
base::internal::BindState<base::RepeatingCallback<void (std::__ndk1::list<BrowsingDataLocalStorageHelper::LocalStorageInfo, std::__ndk1::allocator<BrowsingDataLocalStorageHelper::LocalStorageInfo> > const&)>, std::__ndk1::list<BrowsingDataLocalStorageHelper::LocalStorageInfo, std::__ndk1::allocator<BrowsingDataLocalStorageHelper::LocalStorageInfo> > >::~BindState()
base::internal::BindState<base::RepeatingCallback<void (std::__ndk1::list<BrowsingDataLocalStorageHelper::LocalStorageInfo, std::__ndk1::allocator<BrowsingDataLocalStorageHelper::LocalStorageInfo> > const&)>, std::__ndk1::list<BrowsingDataLocalStorageHelper::LocalStorageInfo, std::__ndk1::allocator<BrowsingDataLocalStorageHelper::LocalStorageInfo> > >::Destroy(base::internal::BindStateBase const*)
base::internal::CallbackBase::~CallbackBase()
base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*)
base::MessageLoop::RunTask(base::PendingTask*)
base::MessageLoop::DoWork()
Java_org_chromium_base_SystemMessageHandler_nativeDoRunLoopOnce


<ref_counted.h:381, name omitted>
base::internal::BindState<void (*)(base::WeakPtr<content::ServiceWorkerContextCore>, long long), base::WeakPtr<content::ServiceWorkerContextCore>, long long>::~BindState()
base::internal::BindState<void (*)(base::WeakPtr<content::ServiceWorkerContextCore>, long long), base::WeakPtr<content::ServiceWorkerContextCore>, long long>::Destroy(base::internal::BindStateBase const*)
base::internal::CallbackBase::~CallbackBase()
base::OnceCallback<void (GURL const&)>::Run(GURL const&) &&
base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*)
base::MessageLoop::RunTask(base::PendingTask*)
base::MessageLoop::DoWork()
Java_org_chromium_base_SystemMessageHandler_nativeDoRunLoopOnce


mojo::edk::Channel::Message::~Message()
mojo::edk::UserMessageImpl::~UserMessageImpl()
mojo::edk::UserMessageImpl::~UserMessageImpl()
mojo::edk::ports::UserMessageEvent::~UserMessageEvent()
mojo::edk::ports::UserMessageEvent::~UserMessageEvent()
mojo::edk::Core::DestroyMessage(unsigned int)
mojo::Message::~Message()
std::__ndk1::__vector_base<mojo::Message, std::__ndk1::allocator<mojo::Message> >::~__vector_base()
IPC::(anonymous namespace)::ChannelAssociatedGroupController::~ChannelAssociatedGroupController()
IPC::(anonymous namespace)::ChannelAssociatedGroupController::~ChannelAssociatedGroupController()
scoped_refptr<IPC::(anonymous namespace)::ChannelAssociatedGroupController>::~scoped_refptr()
base::internal::BindState<void (IPC::(anonymous namespace)::ChannelAssociatedGroupController::*)(mojo::Message), scoped_refptr<IPC::(anonymous namespace)::ChannelAssociatedGroupController>, base::internal::PassedWrapper<mojo::Message> >::Destroy(base::internal::BindStateBase const*)
base::internal::CallbackBase::~CallbackBase()
base::debug::TaskAnnotator::RunTask(char const*, base::PendingTask*)
base::MessageLoop::RunTask(base::PendingTask*)
base::MessageLoop::DoWork()
base::MessagePumpLibevent::Run(base::MessagePump::Delegate*)
<name omitted>
content::BrowserThreadImpl::IOThreadRun(base::RunLoop*)
content::BrowserThreadImpl::Run(base::RunLoop*)
base::Thread::ThreadMain()
base::(anonymous namespace)::ThreadFunc(void*)


Comment 12 by boliu@chromium.org, Oct 19 2017

Cc: tobiasjs@chromium.org
We will miss this entirely in webview, because only google-breakpad microdump lines are captured by the crash forwarder, and minidumps don't get any logs attached at all. It might be possible to change the crash forwarder to capture those lines specifically, though.

Comment 14 by torne@chromium.org, Oct 19 2017

See issue 766752 for a case where heap corruption caused problems in this kind of bindstate case.
Cc: yfried...@chromium.org
Interestingly more than half the crashes are in GPU.
Labels: Stability-Memory

Sign in to add a comment