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_
andcur_range_.end
arenullptr
, or - both
write_ptr_
andcur_range_.end
are not-null and both point to the same memory region.
Ifwrite_ptr_
orcur_range_.end
isnullptr
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:
nullptr + Non-Zero-Integral
is UB,nullptr + Zero-Integral
is well-defined,not-null-ptr +/- null-ptr
are UB,not-null-ptr +/- not-null-ptr
are well-defined if both point to the same memory region,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?
-
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.
-
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:
-
There was a patch submitted here (last updated Apr 19 2022): https://android-review.googlesource.com/c/platform/external/perfetto/+/2063169/3/include/perfetto/protozero/scattered_stream_writer.h -- that patch was rejected. It seems like the primary reason for rejection was this: (comments)
My theory is that if this UB is ever enforced (i.e. if compilers actually start doing anything different) a lot of code everywhere will stop working and people will stop using that version of the compiler.
In other words, pointer arithmetic is, at this point, too big too fail, regardless of the clever and sophisticated way C++ lawyercats worded it. -
Later, UBSan was disabled for the offending function on Mar 14 2023. https://sourcegraph.com/github.com/google/perfetto/-/commit/324d911e28a84855ab7ee7c6768f6ab36e203669
-
The latest release at the time of writing (v33.1) was cut on Mar 3 2023. So if you're using that, you're going to run into the UBSan error.
-
The next release will no longer have this UB error firing, assuming the above patch with
PERFETTO_NO_SANITIZE_UNDEFINED
is not reverted etc.