commit | 199b3b1299ff66b9ea7e0fadb66d5338087eee1a | [log] [tgz] |
---|---|---|
author | Lei YU <mine260309@gmail.com> | Wed Sep 25 17:58:41 2019 +0800 |
committer | Lei YU <mine260309@gmail.com> | Wed Jan 15 14:57:54 2020 +0800 |
tree | 6fd4255afcd542b7450818a067cd3d10af2d9b2d | |
parent | d35c85239a85a101e866a7bd60aff4f40bf77401 [diff] |
Add valgrind suppression On latest OpenBMC, sdbusplus CI fails due to valgrind check like below on ppc64le systems: ==5290== Syscall param epoll_ctl(event) points to uninitialised byte(s) ==5290== at 0x4F2FB08: epoll_ctl (syscall-template.S:79) ==5290== by 0x493A8F7: UnknownInlinedFun (sd-event.c:961) ==5290== by 0x493A8F7: sd_event_add_time (sd-event.c:1019) ==5290== by 0x190BB3: phosphor::Timer::Timer(sd_event*, std::function<void ()>) (timer.hpp:62) ==5290== by 0x192B93: TimerTest::TimerTest() (timer.cpp:25) ==5290== by 0x193A13: TimerTest_timerExpiresAfter2seconds_Test::TimerTest_timerExpiresAfter2seconds_Test() (timer.cpp:85) ==5290== by 0x19E11F: testing::internal::TestFactoryImpl<TimerTest_timerExpiresAfter2seconds_Test>::CreateTest() (gtest-internal.h:472) ==5290== by 0x4A52D3B: HandleSehExceptionsInMethodIfSupported<testing::internal::TestFactoryBase, testing::Test*> (gtest.cc:2447) ==5290== by 0x4A52D3B: testing::Test* testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::TestFactoryBase, testing::Test*>(testing::internal::TestFactoryBase*, testing::Test * (testing::internal::TestFactoryBase::*)(), char const*) (gtest.cc:2483) ==5290== by 0x4A40BCB: Run (gtest.cc:2693) ==5290== by 0x4A40BCB: testing::TestInfo::Run() (gtest.cc:2676) ==5290== by 0x4A40DC3: Run (gtest.cc:2825) ==5290== by 0x4A40DC3: testing::TestCase::Run() (gtest.cc:2810) ==5290== by 0x4A414AF: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:5216) ==5290== by 0x4A5329B: HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool> (gtest.cc:2447) ==5290== by 0x4A5329B: bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl:: *)(), char const*) (gtest.cc:2483) ==5290== by 0x4A416AF: testing::UnitTest::Run() (gtest.cc:4824) ==5290== by 0x4A90917: RUN_ALL_TESTS (gtest.h:2370) ==5290== by 0x4A90917: main (gmock_main.cc:69) ==5290== Address 0x1fff00eafc is on thread 1's stack ==5290== in frame #0, created by epoll_ctl (syscall-template.S:78) ==5290== The root cause is: 1. GCC has a bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77992, that the padding bytes are not initialized. 2. In systemd, the code in [libsystemd/sd-event/sd-event.c][1] using epoll_event hit the above bug: typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ } __EPOLL_PACKED; In glibc, on x86, `__EPOLL_PACKED` is defined as `__attribute__ ((__packed__))`[2], so it's packed and there are no internal padding bytes; On other architectures (e.g. ppc64le), __EPOLL_PACKED is not defined and thus there are 4 internal padding bytes between `events` and `data`, that are not initialized. 3. When epoll_ctl() is invoked, in [Linux kernel][3], it does a copy_from_user() to copy the whole struct into kernel space. That's why Valgrind reports "epoll_ctl(event) points to uninitialised byte(s)", only for non-x86 platforms. 4. The timer test in this repo invokes sd_event_add_time() and eventually hit the above code. The GCC bug is not resolved from 2016. The systemd code is actually correct. There is a [PR][4] sent to systemd trying to workaround the issue, and it is being discussed. Before GCC bug is resolved or systemd PR is accepted, suppress the valgrind error to make it pass the CI. [1]: https://github.com/systemd/systemd/blob/v242/src/libsystemd/sd-event/sd-event.c#L961 [2]: https://github.com/bminor/glibc/blob/f1a0eb5b6762b315517469da47735c51bde6f4ad/sysdeps/unix/sysv/linux/x86/bits/epoll.h#L29 [3]: https://github.com/torvalds/linux/blob/d1eef1c619749b2a57e514a3fa67d9a516ffa919/fs/eventpoll.c#L2095 [4]: https://github.com/systemd/systemd/pull/14353 Signed-off-by: Lei YU <mine260309@gmail.com> Change-Id: I3a29fd0e28e5c7b69037a7ef2ef9571f93d80df7
sdbusplus contains two parts:
The sdbusplus library requires sd-bus, which is contained in libsystemd.
The sdbus++ application requires python and the python libraries mako and py-inflection.
The sdbusplus library builds on top of the sd-bus library to create a modern C++ API for D-Bus. The library attempts to be as lightweight as possible, usually compiling to exactly the sd-bus API calls that would have been necessary, while also providing compile-time type-safety and memory leak protection afforded by modern C++ practices.
Consider the following code:
auto b = bus::new_default_system(); auto m = b.new_method_call("org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager", "ListUsers"); auto reply = b.call(m); std::vector<std::tuple<uint32_t, std::string, message::object_path>> users; reply.read(users);
In a few, relatively succinct, C++ lines this snippet will create a D-Bus connection to the system bus, and call the systemd login manager to get a list of active users. The message and bus objects are automatically freed when they leave scope and the message format strings are generated at compile time based on the types being read. Compare this to the corresponding server code within logind.
In general, the library attempts to mimic the naming conventions of the sd-bus library: ex. sd_bus_call
becomes sdbusplus::bus::call
, sd_bus_get_unique_name
becomes sdbusplus::bus::get_unique_name
, sd_bus_message_get_signature
becomes sdbusplus::message::get_signature
, etc. This allows a relatively straight-forward translation back to the sd-bus functions for looking up the manpage details.
sdbusplus also contains a bindings generator tool: sdbus++
. The purpose of a bindings generator is to reduce the boilerplate associated with creating D-Bus server or client applications. When creating a server application, rather than creating sd-bus vtables and writing C-style functions to handle each vtable callback, you can create a small YAML file to define your D-Bus interface and the sdbus++
tool will create a C++ class that implements your D-Bus interface. This class has a set of virtual functions for each method and property, which you can overload to create your own customized behavior for the interface.
There are currently two types of YAML files: interface and error. Interfaces are used to create server and client D-Bus interfaces. Errors are used to define C++ exceptions which can be thrown and will automatically turn into D-Bus error responses.
[[ D-Bus client bindings are not yet implemented. See openbmc/openbmc#851. ]]
The path of your file will be the interface name. For example, for an interface org.freedesktop.Example
, you would create the files org/freedesktop/Example.interface.yaml
and org/freedesktop/Example.errors.yaml]
for interfaces and errors respectively. These can then be used to generate the server and error bindings:
sdbus++ interface server-header org.freedesktop.Example > \ org/freedesktop/Example/server.hpp sdbus++ interface server-cpp org.freedesktop.Example > \ org/freedesktop/Example/server.cpp sdbus++ error exception-header org.freedesktop.Example > \ org/freedesktop/Example/error.hpp \ sdbus++ error exception-cpp org.freedesktop.Example > \ org/freedesktop/Example/error.cpp
Markdown-based documentation can also be generated from the interface and exception files:
sdbus++ interface markdown org.freedesktop.Example > \ org/freedesktop/Example.md sdbus++ error markdown org.freedesktop.Example >> \ org/freedesktop/Example.md
See the example/Makefile.am
for more details.
Installation of sdbusplus bindings on a custom distribution requires a few packages to be installed prior. Although these packages are the same for several distributions the names of these packages do differ. Below are the packages needed for Ubuntu and Fedora.
sudo apt install git autoconf libtool pkg-config g++ autoconf-archive libsystemd-dev python python-yaml python-mako python-inflection
sudo dnf install git autoconf libtool gcc-c++ pkgconfig autoconf-archive systemd-devel python python-pip python-yaml python-mako
Install the inflection package using the pip utility (on Fedora)
pip install inflection