Address Sanitizer (ASAN) Tool to Debug Memory Corruptions in Chrome OS*

by Sameer Kibey

Overview

Address Sanitizer is a fast memory error detector based on compiler instrumentation (LLVM). This tool is extensively used by Google developers for their internal debug and can detect the following types of bugs:

  • Out-of-bounds accesses to heap, stack and globals
  • Invalid free
  • Use-after-free
  • Use-after-return
  • Double-free

This article describes how to enable and use ASAN tool within the Intel Chromium builds. The article assumes that you are familiar with ebuilds and how to build packages in Chrome OS.

Host setup

Building packages with ASAN enabled:

Inside chroot, run this:

tools/clang/scripts/update.sh

In the ebuild for your package, add clang as the compiler with "-fsanitize=address" flag:

export CC="clang" CXX="clang++"
CXXFLAGS+=" -fsanitize=address"
CFLAGS+=" -fsanitize=address"

Then build the package as follows:

USE="debug" FEATURES="nostrip noclean" CFLAGS="-g -O0" CXXFLAGS="-g -O0" emerge-$board <package-name>

This build will use the clang compiler. You may see compilation failures (clang may throw errors for code that is acceptable to GCC), which you would need to fix.

For Chrome browser you need not modify the ebuild. ASAN is supported with the USE flag. The following will build Chrome browser with asan and clang flags and debug symbols enabled:

USE="asan debug clang chrome_intel_media chrome_media" FEATURES="nostrip noclean" CFLAGS="-g -O0" CXXFLAGS="-g -O0" emerge-$board chromeos-chrome

If you are able to build the package successfully with ASAN, then you can 'gmerge' and remote-install it on target. Otherwise, you may create a new image as usual and flash the target.

Setup on target

  • If ASAN is enabled, then going from browser into shell (ctrl+alt+T) may cause reboot. If you need to use the shell, use ctrl+F2 to go to the chronos shell, which works.
  • Disable sandboxing:  ASAN does not work well with sandboxing. If you leave sandboxing enabled the target device will not boot, or will reboot while booting.
  • Enable the ASAN related flags in /sbin/session_manager_setup.sh (search for ASAN_FLAGS).
  • Now reboot and run your test that you want to debug. If a memory error is detected, ASAN will generate a log file in /var/log/chrome/asan_log.pid. ASAN aborts on the first memory error it detects.

The ASAN log will then need to be symbolized with the correct symbols. The first example below shows the process.

Examples of issues fixed with ASAN:

1. Memory leak in Chrome browser during OpenMax playback

For one of the tests, ASAN generated this output: 

=================================================================
==2504==ERROR: AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs operator delete) on 0x606000301a00
    #0 0x7f788554d7f4 (/opt/google/chrome/chrome+0x1a9e7f4)
    #1 0x7f7890f2166a (/opt/google/chrome/chrome+0xd47266a)
    #2 0x7f7890f211cd (/opt/google/chrome/chrome+0xd4721cd)
    #3 0x7f7890f2a791 (/opt/google/chrome/chrome+0xd47b791)
    #4 0x7f7890f6a5f0 (/opt/google/chrome/chrome+0xd4bb5f0)
    #5 0x7f7890f6a44d (/opt/google/chrome/chrome+0xd4bb44d)
    #6 0x7f7890f6fdf7 (/opt/google/chrome/chrome+0xd4c0df7)
    #7 0x7f7890f6d10e (/opt/google/chrome/chrome+0xd4be10e)
    #8 0x7f7890f6ae91 (/opt/google/chrome/chrome+0xd4bbe91)
    #9 0x7f7890f08015 (/opt/google/chrome/chrome+0xd459015)
    #10 0x7f7890f390ce (/opt/google/chrome/chrome+0xd48a0ce)
    #11 0x7f7886b2400c (/opt/google/chrome/chrome+0x307500c)
    #12 0x7f7886b24924 (/opt/google/chrome/chrome+0x3075924)
    #13 0x7f7886b25a4f (/opt/google/chrome/chrome+0x3076a4f)
    #14 0x7f7886b2cace (/opt/google/chrome/chrome+0x307dace)
    #15 0x7f7886b22bac (/opt/google/chrome/chrome+0x3073bac)
    #16 0x7f7886b6e033 (/opt/google/chrome/chrome+0x30bf033)
    #17 0x7f7886b215cc (/opt/google/chrome/chrome+0x30725cc)
    #18 0x7f7890b58832 (/opt/google/chrome/chrome+0xd0a9832)
    #19 0x7f7886a87bf3 (/opt/google/chrome/chrome+0x2fd8bf3)
    #20 0x7f7886a89804 (/opt/google/chrome/chrome+0x2fda804)
    #21 0x7f7886a859c1 (/opt/google/chrome/chrome+0x2fd69c1)
    #22 0x7f7885560285 (/opt/google/chrome/chrome+0x1ab1285)
    #23 0x7f7881e3c9c6 (/lib64/libc.so.6+0x1f9c6)
0x606000301a00 is located 0 bytes inside of 64-byte region [0x606000301a00,0x606000301a40)
allocated by thread T0 (chrome) here:
    #0 0x7f788554d614 (/opt/google/chrome/chrome+0x1a9e614)
    #1 0x7f7890f26f58 (/opt/google/chrome/chrome+0xd477f58)
    #2 0x7f7890f6c1a1 (/opt/google/chrome/chrome+0xd4bd1a1)
    #3 0x7f7890f6ac99 (/opt/google/chrome/chrome+0xd4bbc99)
    #4 0x7f7890f08015 (/opt/google/chrome/chrome+0xd459015)
    #5 0x7f7890f390ce (/opt/google/chrome/chrome+0xd48a0ce)
    #6 0x7f7886b2400c (/opt/google/chrome/chrome+0x307500c)
    #7 0x7f7886b24924 (/opt/google/chrome/chrome+0x3075924)
    #8 0x7f7886b25a4f (/opt/google/chrome/chrome+0x3076a4f)
    #9 0x7f7886b2cace (/opt/google/chrome/chrome+0x307dace)
    #10 0x7f7886b22bac (/opt/google/chrome/chrome+0x3073bac)
    #11 0x7f7886b6e033 (/opt/google/chrome/chrome+0x30bf033)
    #12 0x7f7886b215cc (/opt/google/chrome/chrome+0x30725cc)
    #13 0x7f7890b58832 (/opt/google/chrome/chrome+0xd0a9832)
    #14 0x7f7886a87bf3 (/opt/google/chrome/chrome+0x2fd8bf3)
    #15 0x7f7886a89804 (/opt/google/chrome/chrome+0x2fda804)
    #16 0x7f7886a859c1 (/opt/google/chrome/chrome+0x2fd69c1)
    #17 0x7f7885560285 (/opt/google/chrome/chrome+0x1ab1285)
    #18 0x7f7881e3c9c6 (/lib64/libc.so.6+0x1f9c6)
==2504==HINT: if you don't care about these warnings you may set ASAN_OPTIONS=alloc_dealloc_mismatch=0
==2504==ABORTING

Symbolize ASAN output

The asan_symbolize.py script can be used to symbolize the ASAN output as follows:

usr/bin/asan_symbolize.py / < asan_log.pid | c++filt

After adding symbols the above ASAN log looks as below. It is now easy to fix the memory leak.

=================================================================
==2504==ERROR: AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs operator delete) on 0x606000301a00
    #0 0x7f788554d7f4 in operator delete _asan_rtl_
    #1 0x7f7890f2166a in ~OmxVideoDecodeAccelerator omx_video_decode_accelerator.cc:228
    #2 0x7f7890f211cd in ~OmxVideoDecodeAccelerator omx_video_decode_accelerator.cc:221
    #3 0x7f7890f2a791 in base::DefaultDeleter<content::OmxVideoDecodeAccelerator>::operator()(content::OmxVideoDecodeAccelerator*) const scoped_ptr.h:137
    #4 0x7f7890f6a5f0 in ~GpuVideoDecodeAccelerator gpu_video_decode_accelerator.cc:150
    #5 0x7f7890f6a44d in ~GpuVideoDecodeAccelerator gpu_video_decode_accelerator.cc:148
    #6 0x7f7890f6fdf7 in content::GpuVideoDecodeAccelerator::OnWillDestroyStub() gpu_video_decode_accelerator.cc:488
    #7 0x7f7890f6d10e in content::GpuVideoDecodeAccelerator::OnDestroy() gpu_video_decode_accelerator.cc:438
    #8 0x7f7890f6ae91 in bool IPC::Message::Dispatch<content::GpuVideoDecodeAccelerator, content::GpuVideoDecodeAccelerator>(IPC::Message const*, content::GpuVideoDecodeAccelerator*, content::GpuVideoDecodeAccelerator*, void (content::GpuVideoDecodeAccelerator::*)()) ipc_message.h:147
    #9 0x7f7890f08015 in content::MessageRouter::RouteMessage(IPC::Message const&) message_router.cc:49
    #10 0x7f7890f390ce in content::GpuChannel::HandleMessage() gpu_channel.cc:815
    #11 0x7f7886b2400c in base::Callback<void ()>::Run() const callback.h:401
    #12 0x7f7886b24924 in base::MessageLoop::DeferOrRunPendingTask(base::PendingTask const&) message_loop.cc:523
    #13 0x7f7886b25a4f in base::MessageLoop::DoWork() message_loop.cc:637
    #14 0x7f7886b2cace in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) message_pump_default.cc:32
    #15 0x7f7886b22bac in base::MessageLoop::RunInternal() message_loop.cc:461
    #16 0x7f7886b6e033 in base::RunLoop::Run() run_loop.cc:47
    #17 0x7f7886b215cc in base::MessageLoop::Run() message_loop.cc:321
    #18 0x7f7890b58832 in content::GpuMain(content::MainFunctionParams const&) gpu_main.cc:318
    #19 0x7f7886a87bf3 in content::RunNamedProcessTypeMain(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, content::MainFunctionParams const&, content::ContentMainDelegate*) content_main_runner.cc:472
    #20 0x7f7886a89804 in content::ContentMainRunnerImpl::Run() content_main_runner.cc:791
    #21 0x7f7886a859c1 in content::ContentMain(int, char const**, content::ContentMainDelegate*) content_main.cc:35
    #22 0x7f7885560285 in ChromeMain chrome_main.cc:39
    #23 0x7f7881e3c9c6 in ?? ??:0
0x606000301a00 is located 0 bytes inside of 64-byte region [0x606000301a00,0x606000301a40)
allocated by thread T0 (chrome) here:
    #0 0x7f788554d614 in operator new[] _asan_rtl_
    #1 0x7f7890f26f58 in content::OmxVideoDecodeAccelerator::AssignPictureBuffers(std::vector<media::PictureBuffer, std::allocator<media::PictureBuffer> > const&) omx_video_decode_accelerator.cc:539
    #2 0x7f7890f6c1a1 in content::GpuVideoDecodeAccelerator::OnAssignPictureBuffers(std::vector<int, std::allocator<int> > const&, std::vector<unsigned int, std::allocator<unsigned int> > const&) gpu_video_decode_accelerator.cc:414
    #3 0x7f7890f6ac99 in void DispatchToMethod<content::GpuVideoDecodeAccelerator, void (content::GpuVideoDecodeAccelerator::*)(std::vector<int, std::allocator<int> > const&, std::vector<unsigned int, std::allocator<unsigned int> > const&), std::vector<int, std::allocator<int> >, std::vector<unsigned int, std::allocator<unsigned int> > >(content::GpuVideoDecodeAccelerator*, void (content::GpuVideoDecodeAccelerator::*)(std::vector<int, std::allocator<int> > const&, std::vector<unsigned int, std::allocator<unsigned int> > const&), Tuple2<std::vector<int, std::allocator<int> >, std::vector<unsigned int, std::allocator<unsigned int> > > const&) tuple.h:555
    #4 0x7f7890f08015 in content::MessageRouter::RouteMessage(IPC::Message const&) message_router.cc:49
    #5 0x7f7890f390ce in content::GpuChannel::HandleMessage() gpu_channel.cc:815
    #6 0x7f7886b2400c in base::Callback<void ()>::Run() const callback.h:401
    #7 0x7f7886b24924 in base::MessageLoop::DeferOrRunPendingTask(base::PendingTask const&) message_loop.cc:523
    #8 0x7f7886b25a4f in base::MessageLoop::DoWork() message_loop.cc:637
    #9 0x7f7886b2cace in base::MessagePumpDefault::Run(base::MessagePump::Delegate*) message_pump_default.cc:32
    #10 0x7f7886b22bac in base::MessageLoop::RunInternal() message_loop.cc:461
    #11 0x7f7886b6e033 in base::RunLoop::Run() run_loop.cc:47
    #12 0x7f7886b215cc in base::MessageLoop::Run() message_loop.cc:321
    #13 0x7f7890b58832 in content::GpuMain(content::MainFunctionParams const&) gpu_main.cc:318
    #14 0x7f7886a87bf3 in content::RunNamedProcessTypeMain(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, content::MainFunctionParams const&, content::ContentMainDelegate*) content_main_runner.cc:472
    #15 0x7f7886a89804 in content::ContentMainRunnerImpl::Run() content_main_runner.cc:791
    #16 0x7f7886a859c1 in content::ContentMain(int, char const**, content::ContentMainDelegate*) content_main.cc:35
    #17 0x7f7885560285 in ChromeMain chrome_main.cc:39
    #18 0x7f7881e3c9c6 in ?? ??:0
==2504==HINT: if you don't care about these warnings you may set ASAN_OPTIONS=alloc_dealloc_mismatch=0
==2504==ABORTING

2. Intermittent segfaults during VP8 playback with Chrome OS on Bay Trail

When playing VP8 clips on Chrome OS with HW accelerated video decode, we were seeing random segmentation fault errors. The dmesg showed the following message:


 [ 34.681156] chrome[19818]: segfault at fffffffc05f46f68 ip 00007f41775a9161 sp 00007f41642af9d0 error 5 in chrome[7f4171783000+7edf000]

GDB showed that the segfault was a result of invalid memory access in the Chrome browser code. Specifically, it was in the tcmalloc code (tcmalloc is Google’s implementation of memory manager for fast mallocs). Based on tcmalloc design, this meant that the bug was a result of memory corruption elsewhere in the VP8 decode stack. So GDB alone is not enough to root cause the issue.

GDB output:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 18089]
0x00007f69384c7987 in MaskPtr (p=<error reading variable: Cannot access memory at address 0xfffffffc04b63d9e>)
    at third_party/tcmalloc/chromium/src/free_list.h:79
79	  return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ mask);
(gdb) bt 
#0  0x00007f69384c7987 in MaskPtr (p=<error reading variable: Cannot access memory at address 0xfffffffc04b63d9e>)
    at third_party/tcmalloc/chromium/src/free_list.h:79
#1  UnmaskPtr (p=<error reading variable: Cannot access memory at address 0xfffffffc04b63d9e>)
    at third_party/tcmalloc/chromium/src/free_list.h:83
#2  FL_Previous_No_Check (t=0xfffffffc04b63d96) at third_party/tcmalloc/chromium/src/free_list.h:89
#3  FL_Next (t=0x3a74351c1100) at third_party/tcmalloc/chromium/src/free_list.h:118
#4  FL_Pop (list=0x7f6935c6bfa0) at third_party/tcmalloc/chromium/src/free_list.h:130
#5  tcmalloc::CentralFreeList::FetchFromSpans (this=this@entry=0x7f693fe75fc0 <tcmalloc::Static::central_cache_+4864>)
    at third_party/tcmalloc/chromium/src/central_freelist.cc:295
.
.

On running this test with ASAN enabled build, the root cause was correctly identified immediately. The ASAN output below shows that the bug was in psb_video driver, which was causing overflow and memory corruption.

=================================================================
==10200==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x606000269be0 at pc 0x7fcc3069ef68 bp 0x7fcc31136310 sp 0x7fcc31136308
WRITE of size 8 at 0x606000269be0 thread T6
    #0 0x7fcc3069ef67 in GetPortId psb_xvva.c:74
    #1 0x7fcc3069db32 in psb_init_xvideo psb_xvva.c:12
    #2 0x7fcc3064ca59 in psb_x11_output_init psb_x11.c:311
    #3 0x7fcc305d3dc3 in psb_initOutput psb_output.c:131
    #4 0x7fcc30599b35 in __vaDriverInit_0_31 psb_drv_video.c:3130
    #5 0x7fcc3059c71a in __vaDriverInit_0_32 psb_drv_video.c:3288
    #6 0x7fcc4a010d08 in ?? ??:0
    #7 0x7fcc4a0119a7 in ?? ??:0
    #8 0x7fcc48b93693 in ?? ??:0
    #9 0x7fcc48b960d7 in ?? ??:0
    #10 0x7fcc48758b9f in ?? ??:0
    #11 0x7fcc4875758d in ?? ??:0
    #12 0x7fcc48dcc6e1 in ComponentBase::Work() componentbase.cpp:1893
    #13 0x7fcc48dce094 in non-virtual thunk to ComponentBase::Work() componentbase.cpp:1923
    #14 0x7fcc4a04c6fb in WorkQueue::DoWork(WorkableInterface*) workqueue.cpp:159
    #15 0x7fcc4a04c479 in WorkQueue::Run() workqueue.cpp:147
    #16 0x7fcc4a049e56 in Thread::Instance(void*) thread.cpp:78
    #17 0x7fcc50aeda93 in WebCore::StyleEngine::insertTreeScopeInDocumentOrder(WTF::ListHashSet<WebCore::TreeScope*, 16ul, WTF::PtrHash<WebCore::TreeScope*> >&, WebCore::TreeScope*) ???:0
    #18 0x7fcc4dc8a0d0 in ?? ??:0
    #19 0x7fcc4d49df0c in ?? ??:0
0x606000269be0 is located 8 bytes to the right of 56-byte region [0x606000269ba0,0x606000269bd8)
allocated by thread T6 here:
    #0 0x7fcc50ae6f84 in WTF::Vector<WTF::RefPtr<WebCore::InsertionPoint>, 0ul>::operator=(WTF::Vector<WTF::RefPtr<WebCore::InsertionPoint>, 0ul> const&) ???:0
    #1 0x7fcc30529990 in ?? ??:0
Thread T6 created by T5 here:
    #0 0x7fcc50ad8881 in WebCore::ExecutionContext::userEventWasHandled() ???:0
    #1 0x7fcc4a049b4a in Thread::Start() thread.cpp:51
    #2 0x7fcc4a04b97b in WorkQueue::StartWork(bool) workqueue.cpp:52
    #3 0x7fcc48dd277f in ComponentBase::TransStateToExecuting(OMX_STATETYPE) componentbase.cpp:1530
    #4 0x7fcc48dc77ba in ComponentBase::TransState(OMX_STATETYPE) componentbase.cpp:1379
    #5 0x7fcc48dc5dc6 in ComponentBase::CmdHandler(cmd_s*) componentbase.cpp:1276
    #6 0x7fcc48dac3d7 in CmdProcessWork::Work() componentbase.cpp:100
    #7 0x7fcc4a04c6fb in WorkQueue::DoWork(WorkableInterface*) workqueue.cpp:159
    #8 0x7fcc4a04c479 in WorkQueue::Run() workqueue.cpp:147
    #9 0x7fcc4a049e56 in Thread::Instance(void*) thread.cpp:78
    #10 0x7fcc50aeda93 in WebCore::StyleEngine::insertTreeScopeInDocumentOrder(WTF::ListHashSet<WebCore::TreeScope*, 16ul, WTF::PtrHash<WebCore::TreeScope*> >&, WebCore::TreeScope*) ???:0
Thread T5 created by T0 (chrome) here:
    #0 0x7fcc50ad8881 in WebCore::ExecutionContext::userEventWasHandled() ???:0
    #1 0x7fcc4a049b4a in Thread::Start() thread.cpp:51
    #2 0x7fcc4a04b97b in WorkQueue::StartWork(bool) workqueue.cpp:52
    #3 0x7fcc48dab0d5 in CmdProcessWork componentbase.cpp:46
    #4 0x7fcc48daf41f in ComponentBase::GetHandle(void**, void*, OMX_CALLBACKTYPE*) componentbase.cpp:244
    #5 0x7fcc4a258772 in OMX_GetHandle wrs_omxcore.cpp:324
    #6 0x7fcc5c4bc3e3 in ?? ??:0
    #7 0x7fcc5c4bbc82 in ?? ??:0
    #8 0x7fcc5c508fe1 in ?? ??:0
    #9 0x7fcc5c4f49e3 in ?? ??:0
    #10 0x7fcc5c4fc4a2 in ?? ??:0
    #11 0x7fcc5c4ec288 in ?? ??:0
    #12 0x7fcc5c4a2015 in ?? ??:0
    #13 0x7fcc5c4d30ce in ?? ??:0
    #14 0x7fcc520be00c in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_S_compare(unsigned long, unsigned long) basic_string.h:411
    #15 0x7fcc520be924 in ash::internal::tray::DriveDetailedView::AppendOperationList(std::vector<ash::DriveOperationStatus, std::allocator<ash::DriveOperationStatus> > const*) tray_drive.cc:331
    #16 0x7fcc520bfa4f in std::vector<ash::DriveOperationStatus, std::allocator<ash::DriveOperationStatus> >::push_back(ash::DriveOperationStatus const&) stl_vector.h:1024
    #17 0x7fcc520c6ace in ash::internal::SpecialPopupRow::AddButton(ash::internal::TrayPopupHeaderButton*) special_popup_row.cc:90
    #18 0x7fcc520bcbac in non-virtual thunk to ash::internal::tray::DriveDetailedView::OperationProgressBar::~OperationProgressBar() tray_drive.cc:128
    #19 0x7fcc52108033 in content::DevToolsTracingHandler::ReadRecordingResult(scoped_refptr<base::RefCountedString> const&) devtools_tracing_handler.cc:86
    #20 0x7fcc520bb5cc in ash::internal::DisplayView::GetExternalDisplayName() tray_display.cc:198
    #21 0x7fcc5c0f2832 in ?? ??:0
    #22 0x7fcc52021bf3 in std::_Rb_tree<aura::Window*, std::pair<aura::Window* const, ui::Layer*>, std::_Select1st<std::pair<aura::Window* const, ui::Layer*> >, std::less<aura::Window*>, std::allocator<std::pair<aura::Window* const, ui::Layer*> > >::_M_get_insert_unique_pos(aura::Window* const&) ???:0
    #23 0x7fcc52023804 in __exchange_and_add_dispatch atomicity.h:81
    #24 0x7fcc5201f9c1 in std::_Vector_base<ash::internal::Resolution, std::allocator<ash::internal::Resolution> >::_M_allocate(unsigned long) new_allocator.h:102
    #25 0x7fcc50afa285 in WebCore::KeyboardEvent::getModifierState(WTF::String const&) const ???:0
    #26 0x7fcc4d3d69c6 in ?? ??:0
Shadow bytes around the buggy address:
  0x0c0c80045320: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c80045330: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c80045340: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c80045350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c80045360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c0c80045370: fa fa fa fa 00 00 00 00 00 00 00 fa[fa]fa fa fa
  0x0c0c80045380: 00 00 00 00 00 00 00 fa fa fa fa fa fd fd fd fd
  0x0c0c80045390: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
  0x0c0c800453a0: fa fa fa fa fd fd fd fd fd fd fd fa fa fa fa fa
  0x0c0c800453b0: fd fd fd fd fd fd fd fa fa fa fa fa fd fd fd fd
  0x0c0c800453c0: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:     fa
  Heap right redzone:    fb
  Freed heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==10200==ABORTING

Here is the source code at fault for the above example, where info is being accessed with out of bounds without check for numAdapt:

static int GetPortId(VADriverContextP ctx, psb_x11_output_p output)
{
   XvAdaptorInfo *info;
   Display *dpy = (Display *)ctx->native_dpy;
   ret = XvQueryAdaptors(dpy, DefaultRootWindow(dpy), &numAdapt, &info);

   /*Force overlay port num equal to one. OverlayC can't be used independently now.*/
    info[1].num_ports = 1;
.
.

Conclusion

ASAN is an extremely useful tool to debug memory corruption related SW bugs. In this article we have shown how to enable ASAN tool in Chrome OS builds. We have shown two real examples on debugging memory corruptions and memory leaks using ASAN on Bay Trail Chromebooks.

Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.