Skip to content

Commit 8458ca6

Browse files
committed
ci: enable AddressSanitizer
1 parent 605712f commit 8458ca6

20 files changed

+369
-145
lines changed

.github/workflows/spread.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ jobs:
3030
set -euo pipefail
3131
3232
if ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}; then
33-
TASKS='"lxd:ubuntu-24.04:spread/build/ubuntu:asan"
34-
"lxd:ubuntu-24.04:spread/build/ubuntu:tsan"
35-
"lxd:ubuntu-24.04:spread/build/ubuntu:asan_clang"
33+
TASKS='"lxd:ubuntu-24.04:spread/build/ubuntu:tsan"
3634
"lxd:ubuntu-24.04:spread/build/ubuntu:tsan_clang"'
3735
fi
3836
@@ -49,6 +47,8 @@ jobs:
4947
"lxd:fedora-rawhide:spread/build/fedora:amd64"
5048
"lxd:ubuntu-24.04:spread/build/sbuild:ubuntu_devel"
5149
"lxd:ubuntu-24.04:spread/build/sbuild:ubuntu_proposed"
50+
"lxd:ubuntu-24.04:spread/build/ubuntu:asan"
51+
"lxd:ubuntu-24.04:spread/build/ubuntu:asan_clang"
5252
"lxd:ubuntu-24.04:spread/build/ubuntu:ubsan"
5353
"lxd:ubuntu-24.04:spread/build/ubuntu:ubsan_clang"'
5454

spread.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ environment:
3737
GCC_VERSION:
3838
GCC_VERSION/ubuntu_devel: 14
3939
DEB_BUILD_EXTRA:
40-
DEB_BUILD_EXTRA/ubsan,ubsan_clang: nostrip
41-
DEB_BUILD_EXTRA/asan,asan_clang,tsan,tsan_clang: nostrip nocheck
40+
DEB_BUILD_EXTRA/asan,asan_clang,ubsan,ubsan_clang: nostrip optimize=-lto
41+
DEB_BUILD_EXTRA/tsan,tsan_clang: nostrip nocheck
4242
DEBOOTSTRAP_OPTS:
4343
DEBOOTSTRAP_OPTS/debian_sid,ubuntu_devel: --no-merged-usr
4444
CTEST_OUTPUT_ON_FAILURE: 1

spread/build/ubuntu/task.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@ execute: |
5353
echo "OVERRIDE_CONFIGURE_OPTIONS += -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" >> debian/opts.mk
5454
5555
# build and run tests
56-
UBSAN_OPTIONS=halt_on_error=1 debian/rules build
56+
UBSAN_OPTIONS=halt_on_error=1 ASAN_OPTIONS=detect_leaks=0,verify_asan_link_order=0,detect_odr_violation=0 debian/rules build
5757
5858
ccache --show-stats --zero-stats > ${CCACHE_DIR}/ccache.stats

src/include/server/mir/scene/text_input_hub.h

+36-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <memory>
2424
#include <optional>
2525
#include <string>
26+
#include <wayland-server.h>
27+
#include <algorithm>
2628

2729
struct wl_array;
2830

@@ -97,6 +99,39 @@ struct TextInputState
9799
std::optional<TextInputContentPurpose> content_purpose;
98100
};
99101

102+
class CopyableWlArray
103+
{
104+
public:
105+
explicit CopyableWlArray(wl_array const* in_data)
106+
{
107+
wl_array_init(&data_);
108+
wl_array_copy(&data_, const_cast<wl_array*>(in_data));
109+
}
110+
111+
CopyableWlArray(CopyableWlArray const& other)
112+
: CopyableWlArray{&other.data_}
113+
{
114+
}
115+
116+
CopyableWlArray& operator=(CopyableWlArray other)
117+
{
118+
std::swap(data_, other.data_);
119+
return *this;
120+
}
121+
122+
~CopyableWlArray()
123+
{
124+
wl_array_release(&data_);
125+
}
126+
127+
[[nodiscard]] wl_array* data() const
128+
{
129+
return const_cast<wl_array*>(&data_);
130+
}
131+
private:
132+
wl_array data_;
133+
};
134+
100135
/// See text-input-unstable-v3.xml for details
101136
struct TextInputChange
102137
{
@@ -142,7 +177,7 @@ struct TextInputChange
142177
std::optional<TextInputKeySym> keysym;
143178

144179
/// \remark Defined for text input v1 and v2, not v3.
145-
std::optional<wl_array*> modifier_map;
180+
std::optional<CopyableWlArray> modifier_map;
146181

147182
/// \remark Defined for text input v1 and v2, not v3.
148183
std::optional<CursorPosition> cursor_position;

src/server/frontend_wayland/input_method_v1.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ class mf::InputMethodV1::Instance : wayland::InputMethodV1
327327

328328
void modifiers_map(struct wl_array *map) override
329329
{
330-
change.pending_change.modifier_map = map;
330+
change.pending_change.modifier_map = scene::CopyableWlArray(map);
331331
change.waiting_status = InputMethodV1ChangeWaitingStatus::none;
332332
}
333333

src/server/frontend_wayland/text_input_v1.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ void TextInputV1::send_text_change(ms::TextInputChange const& change)
289289
}
290290
if (change.modifier_map)
291291
{
292-
send_modifiers_map_event(change.modifier_map.value());
292+
send_modifiers_map_event(change.modifier_map.value().data());
293293
}
294294
if (change.direction)
295295
{

src/server/frontend_wayland/text_input_v2.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ void mf::TextInputV2::send_text_change(ms::TextInputChange const& change)
303303
}
304304
if (change.modifier_map)
305305
{
306-
send_modifiers_map_event(change.modifier_map.value());
306+
send_modifiers_map_event(change.modifier_map.value().data());
307307
}
308308
if (change.direction)
309309
{

src/server/symbols.map

+15-8
Original file line numberDiff line numberDiff line change
@@ -1344,12 +1344,12 @@ local: *;
13441344
MIR_SERVER_INTERNAL_2.18 {
13451345
global:
13461346
extern "C++" {
1347-
mir::DefaultServerConfiguration::the_led_observer_registrar*;
13481347
mir::DecorationStrategy::?DecorationStrategy*;
13491348
mir::DecorationStrategy::DecorationStrategy*;
13501349
mir::DecorationStrategy::operator*;
13511350
mir::DefaultServerConfiguration::set_the_decoration_strategy*;
13521351
mir::DefaultServerConfiguration::the_decoration_strategy*;
1352+
mir::DefaultServerConfiguration::the_led_observer_registrar*;
13531353
mir::Server::set_the_decoration_strategy*;
13541354
mir::Server::the_decoration_strategy*;
13551355
mir::Server::the_idle_handler*;
@@ -1367,8 +1367,17 @@ global:
13671367
mir::input::receiver::XKBMapperRegistrar::set_keymap_for_device*;
13681368
mir::input::receiver::XKBMapperRegistrar::unregister_interest*;
13691369
mir::input::receiver::XKBMapperRegistrar::xkb_modifiers*;
1370+
mir::scene::CopyableWlArray::?CopyableWlArray*;
1371+
mir::scene::CopyableWlArray::CopyableWlArray*;
1372+
mir::scene::CopyableWlArray::data*;
1373+
mir::scene::CopyableWlArray::operator*;
1374+
mir::scene::TextInputChange::?TextInputChange*;
1375+
mir::scene::TextInputChange::operator*;
13701376
mir::shell::IdleHandlerObserver::?IdleHandlerObserver*;
13711377
mir::shell::IdleHandlerObserver::IdleHandlerObserver*;
1378+
non-virtual?thunk?to?mir::DecorationStrategy::?DecorationStrategy*;
1379+
non-virtual?thunk?to?mir::DefaultServerConfiguration::set_the_decoration_strategy*;
1380+
non-virtual?thunk?to?mir::DefaultServerConfiguration::the_decoration_strategy*;
13721381
non-virtual?thunk?to?mir::DefaultServerConfiguration::the_led_observer_registrar*;
13731382
non-virtual?thunk?to?mir::input::receiver::XKBMapperRegistrar::clear_all_keymaps*;
13741383
non-virtual?thunk?to?mir::input::receiver::XKBMapperRegistrar::clear_keymap_for_device*;
@@ -1382,19 +1391,17 @@ global:
13821391
non-virtual?thunk?to?mir::input::receiver::XKBMapperRegistrar::unregister_interest*;
13831392
non-virtual?thunk?to?mir::input::receiver::XKBMapperRegistrar::xkb_modifiers*;
13841393
non-virtual?thunk?to?mir::shell::IdleHandlerObserver::?IdleHandlerObserver*;
1385-
typeinfo?for?mir::input::receiver::XKBMapperRegistrar;
1386-
typeinfo?for?mir::shell::IdleHandlerObserver;
1387-
vtable?for?mir::input::receiver::XKBMapperRegistrar;
1388-
vtable?for?mir::shell::IdleHandlerObserver;
1389-
non-virtual?thunk?to?mir::DecorationStrategy::?DecorationStrategy*;
1390-
non-virtual?thunk?to?mir::DefaultServerConfiguration::set_the_decoration_strategy*;
1391-
non-virtual?thunk?to?mir::DefaultServerConfiguration::the_decoration_strategy*;
13921394
non-virtual?thunk?to?mir::shell::IdleHandlerObserver::?IdleHandlerObserver*;
13931395
typeinfo?for?mir::DecorationStrategy;
1396+
typeinfo?for?mir::input::receiver::XKBMapperRegistrar;
1397+
typeinfo?for?mir::scene::CopyableWlArray;
1398+
typeinfo?for?mir::shell::IdleHandlerObserver;
13941399
typeinfo?for?mir::shell::IdleHandlerObserver;
13951400
virtual?thunk?to?mir::DefaultServerConfiguration::set_the_decoration_strategy*;
13961401
virtual?thunk?to?mir::DefaultServerConfiguration::the_decoration_strategy*;
13971402
vtable?for?mir::DecorationStrategy;
1403+
vtable?for?mir::input::receiver::XKBMapperRegistrar;
1404+
vtable?for?mir::shell::IdleHandlerObserver;
13981405
vtable?for?mir::shell::IdleHandlerObserver;
13991406
};
14001407
} MIR_SERVER_INTERNAL_2.17;

tests/include/mir/test/barrier.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Barrier
3838
void ready()
3939
{
4040
std::unique_lock lock(mutex);
41-
if (--wait_threads)
41+
if ((--wait_threads) > 0)
4242
{
4343
if (!cv.wait_for(lock, std::chrono::minutes(1), [&]{ return wait_threads == 0; }))
4444
throw std::runtime_error("Timeout");

tests/include/mir_test_framework/stub_input_platform.h

+17-8
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,22 @@ class InputDevice;
3636
}
3737
namespace mir_test_framework
3838
{
39+
40+
class DeviceStore
41+
{
42+
public:
43+
virtual ~DeviceStore() = default;
44+
virtual void foreach_device(std::function<void(std::weak_ptr<mir::input::InputDevice> const&)> const&) = 0;
45+
virtual void clear() = 0;
46+
};
47+
3948
class FakeInputDevice;
4049
class StubInputPlatform : public mir::input::Platform
4150
{
4251
public:
43-
explicit StubInputPlatform(std::shared_ptr<mir::input::InputDeviceRegistry> const& input_device_registry);
52+
explicit StubInputPlatform(
53+
std::shared_ptr<mir::input::InputDeviceRegistry> const& input_device_registry,
54+
std::shared_ptr<DeviceStore> const& device_store);
4455
~StubInputPlatform();
4556

4657
std::shared_ptr<mir::dispatch::Dispatchable> dispatchable() override;
@@ -49,18 +60,16 @@ class StubInputPlatform : public mir::input::Platform
4960
void pause_for_config() override;
5061
void continue_after_config() override;
5162

52-
static void add(std::shared_ptr<mir::input::InputDevice> const& dev);
53-
static void remove(std::shared_ptr<mir::input::InputDevice> const& dev);
54-
static void register_dispatchable(std::shared_ptr<mir::dispatch::Dispatchable> const& queue);
55-
static void unregister_dispatchable(std::shared_ptr<mir::dispatch::Dispatchable> const& queue);
63+
void add(std::shared_ptr<mir::input::InputDevice> const& dev);
64+
void remove(std::shared_ptr<mir::input::InputDevice> const& dev);
65+
void register_dispatchable(std::shared_ptr<mir::dispatch::Dispatchable> const& queue);
66+
void unregister_dispatchable(std::shared_ptr<mir::dispatch::Dispatchable> const& queue);
5667

5768
private:
5869
std::shared_ptr<mir::dispatch::MultiplexingDispatchable> const platform_dispatchable;
5970
std::shared_ptr<mir::dispatch::ActionQueue> const platform_queue;
6071
std::shared_ptr<mir::input::InputDeviceRegistry> const registry;
61-
static std::atomic<StubInputPlatform*> stub_input_platform;
62-
static std::vector<std::weak_ptr<mir::input::InputDevice>> device_store;
63-
static std::mutex device_store_guard;
72+
std::shared_ptr<DeviceStore> const device_store;
6473
};
6574

6675
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright © Canonical Ltd.
3+
*
4+
* This program is free software: you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 or 3,
6+
* as published by the Free Software Foundation.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License
14+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
*/
16+
17+
#ifndef MIR_TEST_FRAMEWORK_STUB_INPUT_PLATFORM_ACCESSOR_H
18+
#define MIR_TEST_FRAMEWORK_STUB_INPUT_PLATFORM_ACCESSOR_H
19+
20+
#include "stub_input_platform.h"
21+
22+
namespace mir_test_framework
23+
{
24+
class StubInputPlatformAccessor
25+
{
26+
public:
27+
static mir::UniqueModulePtr<mir::input::Platform> get(std::shared_ptr<mir::input::InputDeviceRegistry> const& input_device_registry);
28+
static void add(std::shared_ptr<mir::input::InputDevice> const& dev);
29+
static void remove(std::shared_ptr<mir::input::InputDevice> const& dev);
30+
static void register_dispatchable(std::shared_ptr<mir::dispatch::Dispatchable> const& queue);
31+
static void unregister_dispatchable(std::shared_ptr<mir::dispatch::Dispatchable> const& queue);
32+
static void clear();
33+
34+
private:
35+
static std::atomic<StubInputPlatform*> stub_input_platform;
36+
37+
};
38+
}
39+
40+
#endif //MIR_TEST_FRAMEWORK_STUB_INPUT_PLATFORM_ACCESSOR_H

tests/mir_test_framework/CMakeLists.txt

+15-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ add_compile_definitions(
2121
string (REPLACE " -flto " " " CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
2222
string (REPLACE " -flto " " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
2323

24+
add_library(mir-stub-input-platform OBJECT
25+
stub_input_platform.cpp
26+
)
27+
28+
target_link_libraries(mir-stub-input-platform
29+
PUBLIC
30+
mirplatform
31+
mircommon
32+
mircore
33+
)
34+
2435
add_library(mir-public-test-framework OBJECT
2536
async_server_runner.cpp
2637
command_line_server_configuration.cpp
@@ -93,6 +104,7 @@ target_link_libraries(mir-umock-test-framework
93104

94105
add_library(mir-test-framework-static STATIC
95106
$<TARGET_OBJECTS:mir-public-test-framework>
107+
$<TARGET_OBJECTS:mir-stub-input-platform>
96108
$<TARGET_OBJECTS:mir-protected-test-framework>
97109
$<TARGET_OBJECTS:mir-public-test>
98110
)
@@ -115,8 +127,8 @@ add_library(
115127
mir-test-input-framework OBJECT
116128

117129
stub_input.cpp
130+
stub_input_platform_accessor.cpp
118131
fake_input_device_impl.cpp
119-
stub_input_platform.cpp
120132
)
121133

122134
target_link_libraries(mir-test-input-framework
@@ -129,7 +141,8 @@ target_link_libraries(mir-test-input-framework
129141
add_library(
130142
mirplatforminputstub MODULE
131143
$<TARGET_OBJECTS:mir-test-input-framework>
132-
$<TARGET_OBJECTS:mirevdevutilsobjects>)
144+
$<TARGET_OBJECTS:mirevdevutilsobjects>
145+
$<TARGET_OBJECTS:mir-stub-input-platform>)
133146
target_link_libraries(mirplatforminputstub mircommon)
134147

135148
set_target_properties(

tests/mir_test_framework/fake_input_device_impl.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
#include "fake_input_device_impl.h"
18-
#include "mir_test_framework/stub_input_platform.h"
18+
#include "mir_test_framework/stub_input_platform_accessor.h"
1919

2020
#include "mir/input/input_device.h"
2121
#include "mir/input/input_device_info.h"
@@ -45,12 +45,12 @@ namespace synthesis = mir::input::synthesis;
4545
mtf::FakeInputDeviceImpl::FakeInputDeviceImpl(mi::InputDeviceInfo const& info)
4646
: queue{std::make_shared<md::ActionQueue>()}, device{std::make_shared<InputDevice>(info, queue)}
4747
{
48-
mtf::StubInputPlatform::add(device);
48+
mtf::StubInputPlatformAccessor::add(device);
4949
}
5050

5151
void mtf::FakeInputDeviceImpl::emit_device_removal()
5252
{
53-
mtf::StubInputPlatform::remove(device);
53+
mtf::StubInputPlatformAccessor::remove(device);
5454
}
5555

5656
void mtf::FakeInputDeviceImpl::emit_runtime_error()
@@ -328,14 +328,14 @@ void mtf::FakeInputDeviceImpl::InputDevice::start(mi::InputSink* destination, mi
328328
{
329329
sink = destination;
330330
builder = event_builder;
331-
mtf::StubInputPlatform::register_dispatchable(queue);
331+
mtf::StubInputPlatformAccessor::register_dispatchable(queue);
332332
}
333333

334334
void mtf::FakeInputDeviceImpl::InputDevice::stop()
335335
{
336336
sink = nullptr;
337337
builder = nullptr;
338-
mtf::StubInputPlatform::unregister_dispatchable(queue);
338+
mtf::StubInputPlatformAccessor::unregister_dispatchable(queue);
339339
}
340340

341341
mi::OutputInfo mtf::FakeInputDeviceImpl::InputDevice::get_output_info() const

tests/mir_test_framework/stub_input.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1515
*/
1616

17-
#include "mir_test_framework/stub_input_platform.h"
17+
#include "mir_test_framework/stub_input_platform_accessor.h"
1818
#include "fake_input_device_impl.h"
1919
#include "mir/module_properties.h"
2020
#include "mir/assert_module_entry_point.h"
@@ -33,7 +33,7 @@ mir::UniqueModulePtr<mi::Platform> create_input_platform(
3333
std::shared_ptr<mi::InputReport> const& /*report*/)
3434
{
3535
mir::assert_entry_point_signature<mi::CreatePlatform>(&create_input_platform);
36-
return mir::make_module_ptr<mtf::StubInputPlatform>(input_device_registry);
36+
return mtf::StubInputPlatformAccessor::get(input_device_registry);
3737
}
3838

3939
void add_input_platform_options(

0 commit comments

Comments
 (0)