google / perfetto

Performance instrumentation and tracing for Android, Linux and Chrome (read-only mirror of https://android.googlesource.com/platform/external/perfetto/)

Home Page:https://www.perfetto.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

The simplest main with perfetto::Tracing::Initialize() failed under ASAN

vglavnyy opened this issue · comments

Perfetto v24.2, Ubuntu clang version 13.0.0-2.

Code sample:

#include <perfetto.h>
#include <chrono>
#include <thread>

PERFETTO_DEFINE_CATEGORIES(perfetto::Category("trace_category").SetDescription(""));
PERFETTO_TRACK_EVENT_STATIC_STORAGE();

int main(int argc, char** argv) {
  (void)argc; (void)argv;
  perfetto::TracingInitArgs args;
  args.backends |= perfetto::kSystemBackend;
  perfetto::Tracing::Initialize(args);
  // perfetto::TrackEvent::Register();
  std::this_thread::sleep_for(std::chrono::milliseconds(100));
  perfetto::TrackEvent::Flush();
  return 0;
}

This code do nothing. It doesn't post any user-defined trace events.
Failure probability depends on std::this_thread::sleep_for. Zero delay or no delay dramatically decrease failure probability.
It fails with or without perfetto::TrackEvent::Register(), perfetto::TrackEvent::Flush().

=================================================================
==92285==ERROR: AddressSanitizer: use-after-poison on address 0x618000000090 at pc 0x55bae63549d9 bp 0x7f3d575fe1a0 sp 0x7f3d575fd960
WRITE of size 48 at 0x618000000090 thread T1
    #0 0x55bae63549d8 in memset (/home/osboxes/Hive/build.debug/test/perfetto_test+0x1e39d8)
    #1 0x55bae640007b in protozero::MessageArena::NewMessage() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:9762:24
    #2 0x55bae63fff7f in protozero::Message::BeginNestedMessageInternal(unsigned int) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:9694:30
    #3 0x55bae655ebea in protozero::Message* protozero::Message::BeginNestedMessage<protozero::Message>(unsigned int) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.h:1712:28
    #4 0x55bae650bc76 in perfetto::protos::gen::IPCFrame::Serialize(protozero::Message*) const /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:63931:41
    #5 0x55bae650becc in perfetto::protos::gen::IPCFrame::SerializeAsArray() const /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:63919:3
    #6 0x55bae6517722 in perfetto::ipc::BufferedFrameDeserializer::Serialize[abi:cxx11](perfetto::protos::gen::IPCFrame const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:66223:40
    #7 0x55bae651865e in perfetto::ipc::ClientImpl::SendFrame(perfetto::protos::gen::IPCFrame const&, int) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:67300:21
    #8 0x55bae6518462 in perfetto::ipc::ClientImpl::BindService(perfetto::base::WeakPtr<perfetto::ipc::ServiceProxy>) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:67253:8
    #9 0x55bae6518dbb in perfetto::ipc::ClientImpl::OnConnect(perfetto::base::UnixSocket*, bool) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:67335:7
    #10 0x55bae65162df in perfetto::base::UnixSocket::OnEvent() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:65718:31
    #11 0x55bae654e996 in perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125::operator()() const /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:65586:17
    #12 0x55bae654e93c in void std::__invoke_impl<void, perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&>(std::__invoke_other, perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14
    #13 0x55bae654e8ec in std::enable_if<is_invocable_r_v<void, perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&>, void>::type std::__invoke_r<void, perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&>(perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:111:2
    #14 0x55bae654e78c in std::_Function_handler<void (), perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:291:9
    #15 0x55bae655a9e4 in std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:560:9
    #16 0x55bae655bf17 in perfetto::base::RunTaskWithWatchdogGuard(std::function<void ()> const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:7135:3
    #17 0x55bae63fd485 in perfetto::base::UnixTaskRunner::RunImmediateAndDelayedTask() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:8179:5
    #18 0x55bae63fc563 in perfetto::base::UnixTaskRunner::Run() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:8116:5
    #19 0x55bae63fc27d in perfetto::base::ThreadTaskRunner::RunTaskThread(std::function<void (perfetto::base::UnixTaskRunner*)>) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:7976:15
    #20 0x55bae65f4359 in void std::__invoke_impl<void, void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> >(std::__invoke_memfun_deref, void (perfetto::base::ThreadTaskRunner::*&&)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*&&, std::function<void (perfetto::base::UnixTaskRunner*)>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:74:14
    #21 0x55bae65f4216 in std::__invoke_result<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> >::type std::__invoke<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> >(void (perfetto::base::ThreadTaskRunner::*&&)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*&&, std::function<void (perfetto::base::UnixTaskRunner*)>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:96:14
    #22 0x55bae65f41ba in void std::thread::_Invoker<std::tuple<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> > >::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:253:13
    #23 0x55bae65f4154 in std::thread::_Invoker<std::tuple<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> > >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:260:11
    #24 0x55bae65f3d78 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> > > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:211:13
    #25 0x7f3d591ec693  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xda693)
    #26 0x7f3d58e80946 in start_thread nptl/pthread_create.c:435:8
    #27 0x7f3d58f10a43 in __clone misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:100

0x618000000090 is located 16 bytes inside of 792-byte region [0x618000000080,0x618000000398)
allocated by thread T1 here:
    #0 0x55bae63eb37d in operator new(unsigned long) (/home/osboxes/Hive/build.debug/test/perfetto_test+0x27a37d)
    #1 0x55bae63f15da in __gnu_cxx::new_allocator<std::_List_node<protozero::MessageArena::Block> >::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/ext/new_allocator.h:127:27
    #2 0x55bae63f15da in std::allocator_traits<std::allocator<std::_List_node<protozero::MessageArena::Block> > >::allocate(std::allocator<std::_List_node<protozero::MessageArena::Block> >&, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/alloc_traits.h:460:20
    #3 0x55bae63f15da in std::__cxx11::_List_base<protozero::MessageArena::Block, std::allocator<protozero::MessageArena::Block> >::_M_get_node() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_list.h:442:16
    #4 0x55bae63f12ef in void std::__cxx11::list<protozero::MessageArena::Block, std::allocator<protozero::MessageArena::Block> >::_M_insert<>(std::_List_iterator<protozero::MessageArena::Block>) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_list.h:1911:18
    #5 0x55bae6400111 in protozero::MessageArena::MessageArena() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:9743:11
    #6 0x55bae65ff9ec in protozero::RootMessage<protozero::Message>::RootMessage() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.h:10581:3
    #7 0x55bae65ff939 in protozero::HeapBuffered<protozero::Message>::HeapBuffered(unsigned long, unsigned long) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.h:10731:3
    #8 0x55bae655e98c in protozero::HeapBuffered<protozero::Message>::HeapBuffered() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.h:10730:20
    #9 0x55bae650bea1 in perfetto::protos::gen::IPCFrame::SerializeAsArray() const /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:63918:51
    #10 0x55bae6517722 in perfetto::ipc::BufferedFrameDeserializer::Serialize[abi:cxx11](perfetto::protos::gen::IPCFrame const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:66223:40
    #11 0x55bae651865e in perfetto::ipc::ClientImpl::SendFrame(perfetto::protos::gen::IPCFrame const&, int) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:67300:21
    #12 0x55bae6518462 in perfetto::ipc::ClientImpl::BindService(perfetto::base::WeakPtr<perfetto::ipc::ServiceProxy>) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:67253:8
    #13 0x55bae6518dbb in perfetto::ipc::ClientImpl::OnConnect(perfetto::base::UnixSocket*, bool) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:67335:7
    #14 0x55bae65162df in perfetto::base::UnixSocket::OnEvent() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:65718:31
    #15 0x55bae654e996 in perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125::operator()() const /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:65586:17
    #16 0x55bae654e93c in void std::__invoke_impl<void, perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&>(std::__invoke_other, perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14
    #17 0x55bae654e8ec in std::enable_if<is_invocable_r_v<void, perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&>, void>::type std::__invoke_r<void, perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&>(perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:111:2
    #18 0x55bae654e78c in std::_Function_handler<void (), perfetto::base::UnixSocket::DoConnect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::$_125>::_M_invoke(std::_Any_data const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:291:9
    #19 0x55bae655a9e4 in std::function<void ()>::operator()() const /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:560:9
    #20 0x55bae655bf17 in perfetto::base::RunTaskWithWatchdogGuard(std::function<void ()> const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:7135:3
    #21 0x55bae63fd485 in perfetto::base::UnixTaskRunner::RunImmediateAndDelayedTask() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:8179:5
    #22 0x55bae63fc563 in perfetto::base::UnixTaskRunner::Run() /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:8116:5
    #23 0x55bae63fc27d in perfetto::base::ThreadTaskRunner::RunTaskThread(std::function<void (perfetto::base::UnixTaskRunner*)>) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:7976:15
    #24 0x55bae65f4359 in void std::__invoke_impl<void, void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> >(std::__invoke_memfun_deref, void (perfetto::base::ThreadTaskRunner::*&&)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*&&, std::function<void (perfetto::base::UnixTaskRunner*)>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:74:14
    #25 0x55bae65f4216 in std::__invoke_result<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> >::type std::__invoke<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> >(void (perfetto::base::ThreadTaskRunner::*&&)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*&&, std::function<void (perfetto::base::UnixTaskRunner*)>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:96:14
    #26 0x55bae65f41ba in void std::thread::_Invoker<std::tuple<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> > >::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:253:13
    #27 0x55bae65f4154 in std::thread::_Invoker<std::tuple<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> > >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:260:11
    #28 0x55bae65f3d78 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (perfetto::base::ThreadTaskRunner::*)(std::function<void (perfetto::base::UnixTaskRunner*)>), perfetto::base::ThreadTaskRunner*, std::function<void (perfetto::base::UnixTaskRunner*)> > > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_thread.h:211:13
    #29 0x7f3d591ec693  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xda693)

Thread T1 created by T0 here:
    #0 0x55bae63a3c5c in pthread_create (/home/osboxes/Hive/build.debug/test/perfetto_test+0x232c5c)
    #1 0x7f3d591ec969 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/lib/x86_64-linux-gnu/libstdc++.so.6+0xda969)
    #2 0x55bae63fbfc9 in perfetto::base::ThreadTaskRunner::ThreadTaskRunner(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:7961:13
    #3 0x55bae65e53f2 in perfetto::base::ThreadTaskRunner::CreateAndStart(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:7754:12
    #4 0x55bae652fa82 in perfetto::(anonymous namespace)::PlatformPosix::CreateTaskRunner(perfetto::Platform::CreateTaskRunnerArgs const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:72540:7
    #5 0x55bae64ac5a9 in perfetto::internal::TracingMuxerImpl::TracingMuxerImpl(perfetto::TracingInitArgs const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:42004:24
    #6 0x55bae64af813 in perfetto::internal::TracingMuxerImpl::InitializeInstance(perfetto::TracingInitArgs const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:42981:9
    #7 0x55bae64b3002 in perfetto::Tracing::InitializeInternal(perfetto::TracingInitArgs const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.cc:43935:3
    #8 0x55bae63ede14 in perfetto::Tracing::Initialize(perfetto::TracingInitArgs const&) /home/osboxes/Hive/build.debug/../subprojects/perfetto-v24.2/sdk/perfetto.h:9888:5
    #9 0x55bae63ede14 in main /home/osboxes/Hive/build.debug/../test/main.cpp:12:2
    #10 0x7f3d58e15fcf in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

SUMMARY: AddressSanitizer: use-after-poison (/home/osboxes/Hive/build.debug/test/perfetto_test+0x1e39d8) in memset
Shadow bytes around the buggy address:
  0x0c307fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff8000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c307fff8010: 00 00[f7]f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x0c307fff8020: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x0c307fff8030: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x0c307fff8040: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x0c307fff8050: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
  0x0c307fff8060: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==92285==ABORTING

Sometimes ASAN reports:

../subprojects/perfetto-v24.2/sdk/perfetto.h:1488:37: runtime error: applying non-zero offset 2 to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../subprojects/perfetto-v24.2/sdk/perfetto.h:1488:37 in 

Are you sue you are building everything with Asan?

Looks like some basic IPC codepaths are reporting violations
We have continuous asan & tsan coverage on ci.perfetto.dev. That should have errored also in our asan.

Can I ask you if you can repro this example in our standalone build with our Asan config?
That would help explaining if this is build-system related or is an actual violation we somehow never spotted so far.

It seems somehow related with the PERFETTO_ASAN_POISON / PERFETTO_ASAN_UNPOISON we have in message_arena.cc

Would be really great if you could help us figure out where this is really coming from.
Can't see on our and and I am more and more convinced this is either:

  • a build-system-related issue
  • A mis-use on our end of those POISON/UNPOISON

@ddiproietto FYI

Actually where is that memset coming from?
I can't see what would cause the
#0 0x55bae63549d8 in memset (/home/osboxes/Hive/build.debug/test/perfetto_test+0x1e39d8)

If some code is memset-ing before this UNPOISON it would explain the ASAN violation.

Can you attach a debugger and see which statement is causing that memset?

I wonder if you are using some debugging version of libcxx (or libstdc++) which does a memset on the std::aligned_storage (here)

Yeah that might be it.
@vglavnyy what are your build flags? Are you passing -DNDEBUG? If not you should.

This is likely due to using Asan with debug features of some C++ library you are using, which does some extra memsets before we UNPOISON our storage.

I wasn't able to reproduce this either (Clang 13.0.1-3). Could you please share your build flags and any options you're passing to ASAN?

Thank you for fast response.
Issued target is the main.cpp file mentioned above.
This this a copy from build.ninja (meson, debug build with -O1):

build test/perfetto_test.p/main.cpp.o: cpp_COMPILER ../test/main.cpp
 DEPFILE = test/perfetto_test.p/main.cpp.o.d
 DEPFILE_UNQUOTED = test/perfetto_test.p/main.cpp.o.d
 ARGS = -Itest/perfetto_test.p -Itest -I../test -I../subprojects/perfetto-v24.2/sdk -Xclang -fcolor-diagnostics -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -Werror -std=c++17 -g -Wextra -Wno-gnu-zero-variadic-macro-arguments -fPIE -g -O1 -fsanitize=address,undefined

build test/perfetto_test: cpp_LINKER test/perfetto_test.p/main.cpp.o | subprojects/perfetto-v24.2/libperfetto.a
 LINK_ARGS = -Wl,--as-needed -Wl,--no-undefined -fuse-ld=lld -pie -Wl,--start-group subprojects/perfetto-v24.2/libperfetto.a -Wl,--end-group -g -fsanitize=address,undefined -pthread

Are you passing -DNDEBUG? If not you should.

The main.cpp was built as debug target so NDEBUG wasn't set for this target.
Where can I find more information about NDEBUG dependency? How this flag affects perfetto library?
Why perfetto's meson.build doesn't add this flag automatically for libperfetto.a?
Or whole target should be built with NDEBUG flag even if a debug target is needed?

Perfetto library is a meson project dependency, it was built (was generated) automatically by meson.

build subprojects/perfetto-v24.2/libperfetto.a.p/sdk_perfetto.cc.o: cpp_COMPILER ../subprojects/perfetto-v24.2/sdk/perfetto.cc
 DEPFILE = subprojects/perfetto-v24.2/libperfetto.a.p/sdk_perfetto.cc.o.d
 DEPFILE_UNQUOTED = subprojects/perfetto-v24.2/libperfetto.a.p/sdk_perfetto.cc.o.d
 ARGS = -Isubprojects/perfetto-v24.2/libperfetto.a.p -Isubprojects/perfetto-v24.2 -I../subprojects/perfetto-v24.2 -Xclang -fcolor-diagnostics -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -Wextra -Wno-gnu-zero-variadic-macro-arguments -fPIC -pthread

build subprojects/perfetto-v24.2/libperfetto.a: STATIC_LINKER subprojects/perfetto-v24.2/libperfetto.a.p/sdk_perfetto.cc.o
 LINK_ARGS = csrD

As I see, I was bad. Perfettor was built without -fsanitize=address,undefined flags.
I will recheck it again with ASAN flags.

Update:
I've checked it with activated ASAN both for perfetto and main.cpp (debug build).
It still failed (v24.2) with message:

../subprojects/perfetto-v24.2/sdk/perfetto.h:1488:37: runtime error: applying non-zero offset 1 to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../subprojects/perfetto-v24.2/sdk/perfetto.h:1488:37 in 
../subprojects/perfetto-v24.2/sdk/perfetto.h:1483:12: runtime error: null pointer passed as argument 1, which is declared to never be null
/usr/include/string.h:44:28: note: nonnull attribute specified here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../subprojects/perfetto-v24.2/sdk/perfetto.h:1483:12 in 

NDEBUG for libperfetto.a target doesn't help.
I will prepare commit with this issue as a standalone build.

@skyostil
ASAN issue disapeared once perfetto static library and the target file have been compiled with the same flags.
But UBSAN issue is still present.
I prepared commit that reproduces one part of initial issue (undefined-behavior).

../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.h:1488:37: runtime error: applying non-zero offset 1 to null pointer
    #0 0x56459126d8cf in protozero::ScatteredStreamWriter::WriteBytes(unsigned char const*, unsigned long) /home/osboxes/projects/perfetto/out/build.issue_271/../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.h:1488:37
    #1 0x56459107f630 in protozero::Message::WriteToStream(unsigned char const*, unsigned char const*) /home/osboxes/projects/perfetto/out/build.issue_271/../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.h:1743:21
    #2 0x56459093c546 in protozero::Message::BeginNestedMessageInternal(unsigned int) /home/osboxes/projects/perfetto/out/build.issue_271/../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.cc:9692:3
    #3 0x5645915e6a6e in perfetto::protos::pbzero::TrackEventCategory* protozero::Message::BeginNestedMessage<perfetto::protos::pbzero::TrackEventCategory>(unsigned int) /home/osboxes/projects/perfetto/out/build.issue_271/../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.h:1712:28
    #4 0x56459118f2df in perfetto::protos::pbzero::TrackEventCategory* perfetto::protos::pbzero::TrackEventDescriptor::add_available_categories<perfetto::protos::pbzero::TrackEventCategory>() /home/osboxes/projects/perfetto/out/build.issue_271/../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.h:26871:12
    #5 0x564590d25235 in perfetto::internal::TrackEventInternal::Initialize(perfetto::internal::TrackEventCategoryRegistry const&, bool (*)(perfetto::protos::gen::DataSourceDescriptor const&)) /home/osboxes/projects/perfetto/out/build.issue_271/../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.cc:43351:21
    #6 0x5645908ea445 in perfetto::internal::TrackEventDataSource<perfetto::TrackEvent, &(perfetto::internal::kCategoryRegistry)>::Register() /home/osboxes/projects/perfetto/out/build.issue_271/../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.h:15711:12
    #7 0x5645908e9bc4 in main /home/osboxes/projects/perfetto/out/build.issue_271/../../issue_271/issue_271.cc:28:2
    #8 0x7fd9dd9d2fcf in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #9 0x7fd9dd9d307c in __libc_start_main csu/../csu/libc-start.c:409:3
    #10 0x564590838984 in _start (/home/osboxes/projects/perfetto/out/build.issue_271/issue_271+0xda1984)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../../issue_271/subprojects/perfetto-v24.2/sdk/perfetto.h:1488:37 in

According this log WriteBytes was called with size=1 when write_ptr_ was nullptr.
Is it serious warning?

UBSAN issue fires in meson build only. It never appears in standalone perfetto build with is_asan = true and is_ubsan = true.
Meson based build uses sdk' files (sdk/perfetto.ccand'sdk/perfetto.h) while perfetto standalone build setting were copied from the client_api_example` target.

If this is false positive I can ignore it using UBSAN .supp file.
I can try to attach to a running target with debugger and check its state if it is need.

This is not dangerous runtime error, because a buffer will be automatically extended inside WriteBytes SlowPath.
But it is UB according to the C++ standard.
https://reviews.llvm.org/D67122
http://eel.is/c++draft/expr.add#4

It can be fixed with

  inline void WriteBytes(const uint8_t* src, size_t size) {
    if (PERFETTO_LIKELY((cur_range_.end - write_ptr_) >= size))
      return WriteBytesUnsafe(src, size);
    WriteBytesSlowPath(src, size);
  }

It will be well defined only if:

  • both write_ptr_ and cur_range_.end are nullptr, or
  • both write_ptr_ and cur_range_.end are not-null and both point to the same memory region.
    If write_ptr_ or cur_range_.end is nullptr while other isn't then UBSAN should generate an error.

Update:
The same fix can be applied in WriteBytesUnsafe.

Just to double check as you claiming that

this is problematic for asan:

    uint8_t* const end = write_ptr_ + size;
    if (PERFETTO_LIKELY(end <= cur_range_.end))

(which could be simplified as if (write_ptr_ + size <= cur_range_.end))

but

  if (cur_range_.end - write_ptr_ >= size)

is not?

Also the thing i'd like to understand first is why none of our asan and ubsan bots did complain about this? WHta's special about the meson build (note: meson is community maintained, we don't actively use/test it)

C++20 standard says:

7.6.6 Additive operators
4 When an expression J that has integral type is added to or subtracted from an expression P of pointer type,
the result has the type of P.
(4.1) — If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value.
(4.2) — Otherwise, if P points to an array element i of an array object x with n elements (9.3.3.4),76 the
expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) array
element i + j of x if 0 ≤ i + j ≤ n and the expression P - J points to the (possibly-hypothetical) array
element i − j of x if 0 ≤ i − j ≤ n.
(4.3) — Otherwise, the behavior is undefined.

5 When two pointer expressions P and Q are subtracted, the type of the result is an implementation-defined
signed integral type; this type shall be the same type that is defined as std::ptrdiff_t in the <cstddef>
header (17.2.4).
(5.1) — If P and Q both evaluate to null pointer values, the result is 0.
(5.2) — Otherwise, if P and Q point to, respectively, array elements i and j of the same array object x, the
expression P - Q has the value i − j.
(5.3) — Otherwise, the behavior is undefined. [Note: If the value i − j is not in the range of representable
values of type std::ptrdiff_t, the behavior is undefined. — end note]

As consequence:

  1. nullptr + Non-Zero-Integral is UB,
  2. nullptr + Zero-Integral is well-defined,
  3. not-null-ptr +/- null-ptr are UB,
  4. not-null-ptr +/- not-null-ptr are well-defined if both point to the same memory region,
  5. null-ptr +/- null-ptr are well-defined,

I propose to use (5) because when the write_ptr_ is null the cur_range_.end is also null.
I tested it, it works in my project. But other solution are also possible (suppress UNSAN at these two lines using pragma).

Also the thing i'd like to understand first is why none of our asan and ubsan bots did complain about this?

It is interesting question.
As I see, the standalone build doesn't use sdk/perfetto.* files in tests, does it?

AH I see thanks for the explanation. It takes a always hours decode C++ lawyercat-style standards.

Part of me goes "this is all BS; if the compiler tries to codegen anything other than the artithmetic that everybody would expect the world would collapse. I've seen these assumptions (about pointer arith just working like integer arith) everywhere, at this point is too late to say: this is UB. the world depends on that UB"

The other part of me goes: if this is as easy to fix as you suggest, and makes ASAN/UBSan stop complaining, can you please send a patch? Seems non controversial enough.

https://perfetto.dev/docs/contributing/getting-started

As I see, the standalone build doesn't use sdk/perfetto.* files in tests, does it?

No. but perfetto.cc/h is really just an amalgamation of all the sources that we have, and those are covered. There is no code in perfetto.{cc,.h} which doesn't exist somewhere in the repo in the non-amalgamated form.

I will prepare patch.

These are compilation flags (connected with -fanitize) for issue_272 target target in standalone build:

cflags = -O0 -funwind-tables -fstrict-aliasing -Wformat -g -fPIC -fstack-protector-strong -Werror -fcolor-diagnostics -fdiagnostics-show-template-tree -Wno-c99-designator -fno-omit-frame-pointer -mavx -mpopcnt -msse4.2 -Wall -Wextra -Wpedantic -Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-gnu-include-next -Wno-gnu-statement-expression -Wno-gnu-zero-variadic-macro-arguments -Wno-padded -Wno-poison-system-directories -Wno-reserved-id-macro -Wno-reserved-identifier -Wno-unknown-sanitizers -Wno-unknown-warning-option -fvisibility=hidden -fno-omit-frame-pointer -fsanitize=address -fsanitize=bounds -fsanitize=float-divide-by-zero -fsanitize=integer-divide-by-zero -fsanitize=null -fsanitize=object-size -fsanitize=return -fsanitize=returns-nonnull-attribute -fsanitize=shift-exponent -fsanitize=signed-integer-overflow -fsanitize=unreachable -fsanitize=vla-bound -fPIE -Wno-unknown-warning-option -Wno-deprecated -Wno-undef -Wno-zero-as-null-pointer-constant -isystem ../../buildtools/protobuf/src
cflags_cc = -std=c++11 -fno-exceptions -fno-rtti -nostdinc++ -isystem../../buildtools/libcxx/include -isystem../../buildtools/libcxxabi/include

and linker flags:

ldflags = -Wl,--build-id -nostdlib++ -pie -Wl,-rpath=\$$ORIGIN/. -Wl,-rpath-link=. -fsanitize=address -fsanitize=undefined
  libs = -lpthread -lrt -ldl

As I see there is no -fsanitize=undefined for in c/cpp flags.
The client_api_example has the same flags (I can attach ninja files)
I'm not sure but these flags looks incorrect. Sanitizers are activated only for C-code and inactive for C++ code.
And USAN is inactive (it activated partially).
I'm not familiar with perfetto code and don't know how to activate UBSAN both for C and CPP.

I'm not familiar with perfetto code and don't know how to activate UBSAN both for C and CPP.

is_ubsan=true in https://perfetto.dev/docs/contributing/build-instructions#build-configurations

But as part of this I just realized that we seem to have removed that config from ci.perfetto.dev (probably to save resources), which explains why we didn't catch this.

also tools/build_all_configs.py will generate the various supported build configs. ubsan specifically under out/linux_ubsan

https://gn.googlesource.com/gn/+/master/docs/reference.md#var_cflags

  "cflags" are passed to all invocations of the C, C++, Objective C, and
  Objective C++ compilers.

So, ccflags is enough for GN.

I've tried to add full UBSAN support with -fsanitize=undefined under is_ubsan.
But building system can't compile with this flag, it failed with:

UMMARY: UndefinedBehaviorSanitizer: stack-overflow /b/s/w/ir/cache/builder/src/third_party/llvm/compiler-rt/lib/ubsan/ubsan_handlers_cxx.cpp:36:7 in HandleDynamicTypeCacheMiss(__ubsan::DynamicTypeCacheMissData*, unsigned long, unsigned long, __ubsan::ReportOptions)
==200133==ABORTING
Traceback (most recent call last):
  File "/home/osboxes/projects/perfetto/out/u18/../../gn/standalone/protoc.py", line 60, in <module>
    sys.exit(main())
  File "/home/osboxes/projects/perfetto/out/u18/../../gn/standalone/protoc.py", line 56, in main
    subprocess.check_call(sys.argv[1:])
  File "/usr/lib/python3.9/subprocess.py", line 373, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['./protoc', '--proto_path', '../../', '--cpp_out', 'lite=true:gen/', '../../protos/perfetto/config/inode_file/inode_file_config.proto']' returned non-zero exit status 1.
ninja: build stopped: subcommand failed.

UBSAN detected stack-overflow inside ubsan_handlers_cxx.cpp.

Since initial commit 0825bc8 of build/sanitizers/BUILD.gn it uses limited subset of UBSAN options.
It might be a reason why discussed "applying non-zero offset 1 to null pointer" wasn't detected.

Clang-13 (is_system_compiler=true) is also failed with -fsanitize=undefined flag:

SUMMARY: UndefinedBehaviorSanitizer: stack-overflow /home/osboxes/projects/perfetto/out/u18/../../buildtools/libcxxabi/src/private_typeinfo.cpp:60 in is_equal(std::type_info const*, std::type_info const*, bool)
==201729==ABORTING
Traceback (most recent call last):
  File "/home/osboxes/projects/perfetto/out/u18/../../gn/standalone/protoc.py", line 60, in <module>
    sys.exit(main())
  File "/home/osboxes/projects/perfetto/out/u18/../../gn/standalone/protoc.py", line 56, in main
    subprocess.check_call(sys.argv[1:])
  File "/usr/lib/python3.9/subprocess.py", line 373, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['./protoc', '--proto_path', '../../', '--cpp_out', 'lite=true:gen/', '../../protos/perfetto/config/gpu/gpu_counter_config.proto', '../../protos/perfetto/config/gpu/vulkan_memory_config.proto']' returned non-zero exit status 1.

Probably both failed in './protoc' that was built in previous stage with -fsanitize=undefined.

Sorry I am getting a bit lost in this bug, it feels like every message talks about some slightly different issue. I am struggling to keep up.
can we take a step back and sort this out in steps?

  1. Let's get in a state where is_ubsan=true in GN args actually makes UBsan shout. I don't want to look into ubsan reports if the build system is not properly setup. It feels many of the issues here are of the form "ah no I am passing inconsistent cflags". Please DO propose a fix on the UBsan setup via GN+ninja first.

  2. Once the build system is setup, I expect all the real violation to be reproducible. Once that happens let's discuss them one by one.

Right now it's all too chaotic.

The title of this issue is wrong.
ASAN error was result of mismatched compilation flags.

The actual issue is errors detected by UBSAN.
It happens if a project uses perfetto sdk library with -fsanitize=undefined compilation flag.
With this option UBSAN detects errors in sdk/perfetto.h, e.g:

../subprojects/perfetto-v24.2/sdk/perfetto.h:1488:37: runtime error: applying non-zero offset 1 to null pointer
    #0 0x56459126d8cf in protozero::ScatteredStreamWriter::WriteBytes(unsigned char const*, unsigned long)

Also, applying non-zero offset 1 to null pointer and applying non-zero offset 2 to null pointer errors are reported
by UBSAN for that sdk/perfetto.h file.

After code review, I concluded that these detected UBSAN errors are formal UB.
They could be ignored since they are isolated and don't affects an user code.

Solution
These detected errors can be supressed using UBSAN suppression file:

UBSAN_OPTIONS=suppressions=UBSanSuppression.supp

Possible content of UBSanSuppression.supp:

# suppress memcpy(?nullptr, ?nullptr, 0) in perfetto
nonnull-attribute:perfetto.*
# suppress 'nullptr' + non-zero-intergal-offset in perfetto
pointer-overflow:perfetto.*

How to reproduce it in perfetto standalone build

These UBSAN errors are avoided by perfetto standalone build (perfetto_unittests, perfetto_integrationtests).
However, they can be reproduced if activate -fsanitize=undefined for is_ubsan=true builds.
To do this, one can add into gn/standalone/sanitizers/BUILD.gn the following two lines:

if (is_ubsan) {
    cflags += [
    "-fsanitize=undefined", # enable almost all UBSAN checks
    "-fno-sanitize=vptr",   # disable vptr check enabled by `undefined` because of `no-rtti`
    "-fsanitize=bounds",
    "-fsanitize=float-divide-by-zero",
    ...

With enabled -fsanitize=undefined, the above mentioned USAN runtime errors are reported for perfetto_unittests target:

../include/perfetto/protozero/scattered_stream_writer.h:74:37: runtime error: applying non-zero offset 2 to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../include/perfetto/protozero/scattered_stream_writer.h:74:37 in 
../include/perfetto/protozero/scattered_stream_writer.h:69:24: runtime error: null pointer passed as argument 2, which is declared to never be null
/usr/include/string.h:44:28: note: nonnull attribute specified here
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../include/perfetto/protozero/scattered_stream_writer.h:69:24 in 

Conclusion

This issue can be closed. I can rename the title and can remove all unrelated messages if needed.

In case anyone else like me is confused as to why this issue was closed without a linked PR/patch to fix the UB problem, here's a quick summary as I understand it: