Mir

Merge lp:~mir-team/mir/fix-1376324-0.8 into lp:mir/0.8

Proposed by Daniel van Vugt
Status: Merged
Approved by: Cemil Azizoglu
Approved revision: no longer in the source branch.
Merged at revision: 1969
Proposed branch: lp:~mir-team/mir/fix-1376324-0.8
Merge into: lp:mir/0.8
Diff against target: 368 lines (+186/-1)
16 files modified
CMakeLists.txt (+1/-1)
debian/changelog (+10/-0)
src/include/server/mir/compositor/buffer_stream.h (+1/-0)
src/server/compositor/buffer_bundle.h (+1/-0)
src/server/compositor/buffer_queue.cpp (+11/-0)
src/server/compositor/buffer_queue.h (+2/-0)
src/server/compositor/buffer_stream_surfaces.cpp (+5/-0)
src/server/compositor/buffer_stream_surfaces.h (+1/-0)
src/server/scene/basic_surface.cpp (+3/-0)
tests/include/mir_test_doubles/mock_buffer_bundle.h (+1/-0)
tests/include/mir_test_doubles/mock_buffer_stream.h (+1/-0)
tests/include/mir_test_doubles/stub_buffer_stream.h (+1/-0)
tests/integration-tests/CMakeLists.txt (+1/-0)
tests/integration-tests/surface_composition.cpp (+125/-0)
tests/integration-tests/test_exchange_buffer.cpp (+1/-0)
tests/unit-tests/compositor/test_buffer_queue.cpp (+21/-0)
To merge this branch: bzr merge lp:~mir-team/mir/fix-1376324-0.8
Reviewer Review Type Date Requested Status
Cemil Azizoglu (community) Approve
Robert Carr (community) Approve
Review via email: mp+246280@code.launchpad.net

Commit message

Backport fix for USC crash LP: #1376324

Description of the change

Because if you look closely, it's still crashing for RTM devices (Mir 0.8.0) that lack the fix:
https://errors.ubuntu.com/problem/bfb855ebc60f251bf495a2ffb24f2924c50bdbf8

Look closer again and you'll see evidence of vivid (Mir 0.9 devices) crashing too. But I think that's actually a different bug with the same basic signature -> bug 1401488 that only exists in 0.9 and later.

So in theory, this fix is all that's needed for 0.8 and RTM.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Yeah I know it's probably too late for 0.8.1 now we have a revision in QA already. This might be a good idea for 0.8.2 later though.

Discuss.

Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Daniel, thanks for being on top of the bugs and raising. We'll try to convince product owners to land this.

review: Approve
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

(Let's try this again)

Daniel, thanks for being on top of the bugs and bringing attention to this. We'll try to convince product owners to land it.

review: Approve
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Daniel, I just noticed Saviq's silo has landed. So we should probably merge back the bot's changelog changes also.

Product owners have approved it. I'll probably put it in a silo tomorrow.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Cemil: The bot's changelog is grossly incorrect as mentioned in email.. And it makes me suspicious of what actually landed.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

BTW, I don't know where the silo landed too -- I haven't yet found any branch having been updated yet.

Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

Silo landed on RTM. As Saviq mentioned in an email, the train updates the changelog like that when the branch has never been used to land in RTM before. Up until Saviq's landing, it had been only used for ubuntu and then the source package was used to sync to rtm.

This will land in 0.8.2 (which means this branch needs to be updated with the correct PATCH version etc.).

Revision history for this message
Robert Carr (robertcarr) wrote :

looks ok to me. ABI looks unchanged.

review: Approve
Revision history for this message
Cemil Azizoglu (cemil-azizoglu) wrote :

All tests passed. In the QA queue now.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Should we expect some script/robot/silo to land this or is manual intervention required?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2015-01-12 04:17:53 +0000
+++ CMakeLists.txt 2015-01-15 03:19:37 +0000
@@ -28,7 +28,7 @@
2828
29set(MIR_VERSION_MAJOR 0)29set(MIR_VERSION_MAJOR 0)
30set(MIR_VERSION_MINOR 8) # This should change at least with every MIRSERVER_ABI30set(MIR_VERSION_MINOR 8) # This should change at least with every MIRSERVER_ABI
31set(MIR_VERSION_PATCH 1)31set(MIR_VERSION_PATCH 2)
3232
33set(MIR_VERSION ${MIR_VERSION_MAJOR}.${MIR_VERSION_MINOR}.${MIR_VERSION_PATCH})33set(MIR_VERSION ${MIR_VERSION_MAJOR}.${MIR_VERSION_MINOR}.${MIR_VERSION_PATCH})
3434
3535
=== modified file 'debian/changelog'
--- debian/changelog 2015-01-15 03:13:20 +0000
+++ debian/changelog 2015-01-15 03:19:37 +0000
@@ -1,3 +1,13 @@
1mir (0.8.2-0ubuntu1) UNRELEASED; urgency=medium
2
3 * Bug fix release 0.8.2 (https://launchpad.net/mir/+milestone/0.8.2)
4 - ABIs all unchanged. No downstream projects need rebuilding.
5 - Fixes bug: Crash in /usr/sbin/unity-system-compositor:*** Error in
6 `unity-system-compositor': free(): invalid pointer: ADDR ***
7 (LP: #1376324)
8
9 -- Daniel van Vugt <daniel.van.vugt@canonical.com> Thu, 15 Jan 2015 11:15:07 +0800
10
1mir (0.8.1+15.04.20150112.2~rtm-0ubuntu1) 14.09; urgency=medium11mir (0.8.1+15.04.20150112.2~rtm-0ubuntu1) 14.09; urgency=medium
212
3 [ Daniel van Vugt ]13 [ Daniel van Vugt ]
414
=== modified file 'src/include/server/mir/compositor/buffer_stream.h'
--- src/include/server/mir/compositor/buffer_stream.h 2014-09-11 05:51:44 +0000
+++ src/include/server/mir/compositor/buffer_stream.h 2015-01-15 03:19:37 +0000
@@ -54,6 +54,7 @@
54 virtual void force_requests_to_complete() = 0;54 virtual void force_requests_to_complete() = 0;
55 virtual int buffers_ready_for_compositor() const = 0;55 virtual int buffers_ready_for_compositor() const = 0;
56 virtual void drop_old_buffers() = 0;56 virtual void drop_old_buffers() = 0;
57 virtual void drop_client_requests() = 0;
57};58};
5859
59}60}
6061
=== modified file 'src/server/compositor/buffer_bundle.h'
--- src/server/compositor/buffer_bundle.h 2014-09-11 05:51:44 +0000
+++ src/server/compositor/buffer_bundle.h 2015-01-15 03:19:37 +0000
@@ -68,6 +68,7 @@
68 */68 */
69 virtual int buffers_free_for_client() const = 0;69 virtual int buffers_free_for_client() const = 0;
70 virtual void drop_old_buffers() = 0;70 virtual void drop_old_buffers() = 0;
71 virtual void drop_client_requests() = 0;
7172
72protected:73protected:
73 BufferBundle() = default;74 BufferBundle() = default;
7475
=== modified file 'src/server/compositor/buffer_queue.cpp'
--- src/server/compositor/buffer_queue.cpp 2014-09-30 06:11:33 +0000
+++ src/server/compositor/buffer_queue.cpp 2015-01-15 03:19:37 +0000
@@ -100,6 +100,7 @@
100 frame_dropping_enabled{false},100 frame_dropping_enabled{false},
101 the_properties{props},101 the_properties{props},
102 force_new_compositor_buffer{false},102 force_new_compositor_buffer{false},
103 callbacks_allowed{true},
103 gralloc{gralloc}104 gralloc{gralloc}
104{105{
105 if (nbuffers < 1)106 if (nbuffers < 1)
@@ -434,6 +435,9 @@
434 [&]{ return !contains(buffer, pending_snapshots); });435 [&]{ return !contains(buffer, pending_snapshots); });
435 }436 }
436437
438 if (!callbacks_allowed) // We're shutting down
439 return;
440
437 buffers_owned_by_client.push_back(buffer);441 buffers_owned_by_client.push_back(buffer);
438442
439 lock.unlock();443 lock.unlock();
@@ -502,3 +506,10 @@
502 release(buffer, std::move(lock));506 release(buffer, std::move(lock));
503 }507 }
504}508}
509
510void mc::BufferQueue::drop_client_requests()
511{
512 std::unique_lock<std::mutex> lock(guard);
513 callbacks_allowed = false;
514 pending_client_notifications.clear();
515}
505516
=== modified file 'src/server/compositor/buffer_queue.h'
--- src/server/compositor/buffer_queue.h 2014-09-30 06:11:33 +0000
+++ src/server/compositor/buffer_queue.h 2015-01-15 03:19:37 +0000
@@ -63,6 +63,7 @@
63 bool framedropping_allowed() const;63 bool framedropping_allowed() const;
64 bool is_a_current_buffer_user(void const* user_id) const;64 bool is_a_current_buffer_user(void const* user_id) const;
65 void drop_old_buffers() override;65 void drop_old_buffers() override;
66 void drop_client_requests() override;
6667
67private:68private:
68 void give_buffer_to_client(graphics::Buffer* buffer,69 void give_buffer_to_client(graphics::Buffer* buffer,
@@ -89,6 +90,7 @@
89 bool frame_dropping_enabled;90 bool frame_dropping_enabled;
90 graphics::BufferProperties the_properties;91 graphics::BufferProperties the_properties;
91 bool force_new_compositor_buffer;92 bool force_new_compositor_buffer;
93 bool callbacks_allowed;
9294
93 std::condition_variable snapshot_released;95 std::condition_variable snapshot_released;
94 std::shared_ptr<graphics::GraphicBufferAllocator> gralloc;96 std::shared_ptr<graphics::GraphicBufferAllocator> gralloc;
9597
=== modified file 'src/server/compositor/buffer_stream_surfaces.cpp'
--- src/server/compositor/buffer_stream_surfaces.cpp 2014-09-11 05:51:44 +0000
+++ src/server/compositor/buffer_stream_surfaces.cpp 2015-01-15 03:19:37 +0000
@@ -94,3 +94,8 @@
94{94{
95 buffer_bundle->drop_old_buffers();95 buffer_bundle->drop_old_buffers();
96}96}
97
98void mc::BufferStreamSurfaces::drop_client_requests()
99{
100 buffer_bundle->drop_client_requests();
101}
97102
=== modified file 'src/server/compositor/buffer_stream_surfaces.h'
--- src/server/compositor/buffer_stream_surfaces.h 2014-09-11 05:51:44 +0000
+++ src/server/compositor/buffer_stream_surfaces.h 2015-01-15 03:19:37 +0000
@@ -53,6 +53,7 @@
53 void force_requests_to_complete() override;53 void force_requests_to_complete() override;
54 int buffers_ready_for_compositor() const override;54 int buffers_ready_for_compositor() const override;
55 void drop_old_buffers() override;55 void drop_old_buffers() override;
56 void drop_client_requests() override;
5657
57protected:58protected:
58 BufferStreamSurfaces(const BufferStreamSurfaces&) = delete;59 BufferStreamSurfaces(const BufferStreamSurfaces&) = delete;
5960
=== modified file 'src/server/scene/basic_surface.cpp'
--- src/server/scene/basic_surface.cpp 2014-09-26 08:16:25 +0000
+++ src/server/scene/basic_surface.cpp 2015-01-15 03:19:37 +0000
@@ -151,6 +151,9 @@
151ms::BasicSurface::~BasicSurface() noexcept151ms::BasicSurface::~BasicSurface() noexcept
152{152{
153 report->surface_deleted(this, surface_name);153 report->surface_deleted(this, surface_name);
154
155 if (surface_buffer_stream) // some tests use null for surface_buffer_stream
156 surface_buffer_stream->drop_client_requests();
154}157}
155158
156std::shared_ptr<mc::BufferStream> ms::BasicSurface::buffer_stream() const159std::shared_ptr<mc::BufferStream> ms::BasicSurface::buffer_stream() const
157160
=== modified file 'tests/include/mir_test_doubles/mock_buffer_bundle.h'
--- tests/include/mir_test_doubles/mock_buffer_bundle.h 2014-09-11 05:51:44 +0000
+++ tests/include/mir_test_doubles/mock_buffer_bundle.h 2015-01-15 03:19:37 +0000
@@ -51,6 +51,7 @@
51 MOCK_METHOD0(drop_old_buffers, void());51 MOCK_METHOD0(drop_old_buffers, void());
52 int buffers_ready_for_compositor() const override { return 1; }52 int buffers_ready_for_compositor() const override { return 1; }
53 int buffers_free_for_client() const override { return 1; }53 int buffers_free_for_client() const override { return 1; }
54 void drop_client_requests() override {}
54};55};
5556
56}57}
5758
=== modified file 'tests/include/mir_test_doubles/mock_buffer_stream.h'
--- tests/include/mir_test_doubles/mock_buffer_stream.h 2014-09-11 05:51:44 +0000
+++ tests/include/mir_test_doubles/mock_buffer_stream.h 2015-01-15 03:19:37 +0000
@@ -58,6 +58,7 @@
58 MOCK_METHOD0(force_requests_to_complete, void());58 MOCK_METHOD0(force_requests_to_complete, void());
59 MOCK_CONST_METHOD0(buffers_ready_for_compositor, int());59 MOCK_CONST_METHOD0(buffers_ready_for_compositor, int());
60 MOCK_METHOD0(drop_old_buffers, void());60 MOCK_METHOD0(drop_old_buffers, void());
61 MOCK_METHOD0(drop_client_requests, void());
61};62};
62}63}
63}64}
6465
=== modified file 'tests/include/mir_test_doubles/stub_buffer_stream.h'
--- tests/include/mir_test_doubles/stub_buffer_stream.h 2014-09-11 05:51:44 +0000
+++ tests/include/mir_test_doubles/stub_buffer_stream.h 2015-01-15 03:19:37 +0000
@@ -82,6 +82,7 @@
82 int buffers_ready_for_compositor() const override { return 1; }82 int buffers_ready_for_compositor() const override { return 1; }
8383
84 void drop_old_buffers() override {}84 void drop_old_buffers() override {}
85 void drop_client_requests() override {}
8586
86 StubBuffer stub_client_buffer;87 StubBuffer stub_client_buffer;
87 std::shared_ptr<graphics::Buffer> stub_compositor_buffer;88 std::shared_ptr<graphics::Buffer> stub_compositor_buffer;
8889
=== modified file 'tests/integration-tests/CMakeLists.txt'
--- tests/integration-tests/CMakeLists.txt 2014-10-03 20:09:41 +0000
+++ tests/integration-tests/CMakeLists.txt 2015-01-15 03:19:37 +0000
@@ -24,6 +24,7 @@
24 test_session_manager.cpp24 test_session_manager.cpp
25 test_session.cpp25 test_session.cpp
26 session_management.cpp26 session_management.cpp
27 surface_composition.cpp
27)28)
2829
29add_subdirectory(client/)30add_subdirectory(client/)
3031
=== added file 'tests/integration-tests/surface_composition.cpp'
--- tests/integration-tests/surface_composition.cpp 1970-01-01 00:00:00 +0000
+++ tests/integration-tests/surface_composition.cpp 2015-01-15 03:19:37 +0000
@@ -0,0 +1,125 @@
1/*
2 * Copyright © 2014 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 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 * Authored By: Alan Griffiths <alan@octopull.co.uk>
17 */
18
19#include "src/server/scene/basic_surface.h"
20#include "src/server/report/null_report_factory.h"
21#include "src/server/compositor/buffer_stream_surfaces.h"
22#include "src/server/compositor/buffer_queue.h"
23
24#include "mir_test_doubles/null_surface_configurator.h"
25#include "mir_test_doubles/stub_buffer_allocator.h"
26#include "mir_test_doubles/stub_frame_dropping_policy_factory.h"
27#include "mir_test_doubles/stub_input_sender.h"
28
29#include <gmock/gmock.h>
30#include <gtest/gtest.h>
31
32namespace geom = mir::geometry;
33namespace mc = mir::compositor;
34namespace mg = mir::graphics;
35namespace mi = mir::input;
36namespace mr = mir::report;
37namespace ms = mir::scene;
38namespace mtd = mir::test::doubles;
39
40using namespace testing;
41
42namespace
43{
44struct SurfaceComposition : Test
45{
46 auto create_surface() const
47 -> std::shared_ptr<ms::Surface>
48 {
49 return std::make_shared<ms::BasicSurface>(
50 std::string("SurfaceComposition"),
51 geom::Rectangle{{},{}},
52 false,
53 create_buffer_stream(),
54 create_input_channel(),
55 create_input_sender(),
56 create_surface_configurator(),
57 create_cursor_image(),
58 mr::null_scene_report());
59
60 }
61
62 int const number_of_buffers = 3;
63
64 auto create_buffer_stream() const
65 ->std::shared_ptr<mc::BufferStream>
66 {
67 return std::make_shared<mc::BufferStreamSurfaces>(create_buffer_bundle());
68 }
69
70 auto create_buffer_bundle() const
71 -> std::shared_ptr<mc::BufferBundle>
72 {
73 return std::make_shared<mc::BufferQueue>(
74 number_of_buffers,
75 allocator,
76 basic_properties,
77 policy_factory);
78 }
79
80 auto create_input_channel() const
81 -> std::shared_ptr<mi::InputChannel> { return {}; }
82
83 auto create_cursor_image() const
84 -> std::shared_ptr<mg::CursorImage> { return {}; }
85
86 auto create_surface_configurator() const
87 -> std::shared_ptr<ms::SurfaceConfigurator>
88 { return std::make_shared<mtd::NullSurfaceConfigurator>(); }
89
90 auto create_input_sender() const
91 -> std::shared_ptr<mi::InputSender>
92 { return std::make_shared<mtd::StubInputSender>(); }
93
94 std::shared_ptr<mg::GraphicBufferAllocator> const allocator
95 {std::make_shared<mtd::StubBufferAllocator>()};
96
97 mg::BufferProperties const basic_properties
98 { geom::Size{3, 4}, mir_pixel_format_abgr_8888, mg::BufferUsage::hardware };
99
100 mtd::StubFrameDroppingPolicyFactory policy_factory;
101};
102}
103
104// Presumptive cause of lp:1376324
105TEST_F(SurfaceComposition, does_not_send_client_buffers_to_dead_surfaces)
106{
107 auto surface = create_surface();
108
109 mg::Buffer* old_buffer{nullptr};
110
111 auto const callback = [&] (mg::Buffer* new_buffer)
112 {
113 // If surface is dead then callback is not expected
114 EXPECT_THAT(surface.get(), NotNull());
115 old_buffer = new_buffer;
116 };
117
118 // Exhaust the buffers to ensure we have a pending swap to complete
119 for (auto i = 0; i != number_of_buffers; ++i)
120 surface->swap_buffers(old_buffer, callback);
121
122 auto const renderable = surface->compositor_snapshot(this);
123
124 surface.reset();
125}
0126
=== modified file 'tests/integration-tests/test_exchange_buffer.cpp'
--- tests/integration-tests/test_exchange_buffer.cpp 2014-09-15 18:20:14 +0000
+++ tests/integration-tests/test_exchange_buffer.cpp 2015-01-15 03:19:37 +0000
@@ -78,6 +78,7 @@
78 void force_requests_to_complete() {};78 void force_requests_to_complete() {};
79 int buffers_ready_for_compositor() const { return -5; }79 int buffers_ready_for_compositor() const { return -5; }
80 void drop_old_buffers() {}80 void drop_old_buffers() {}
81 void drop_client_requests() override {}
8182
82 std::vector<std::shared_ptr<mg::Buffer>> client_buffers;83 std::vector<std::shared_ptr<mg::Buffer>> client_buffers;
83 std::vector<mg::BufferID> const buffer_id_seq;84 std::vector<mg::BufferID> const buffer_id_seq;
8485
=== modified file 'tests/unit-tests/compositor/test_buffer_queue.cpp'
--- tests/unit-tests/compositor/test_buffer_queue.cpp 2014-09-30 06:11:33 +0000
+++ tests/unit-tests/compositor/test_buffer_queue.cpp 2015-01-15 03:19:37 +0000
@@ -695,6 +695,27 @@
695 }695 }
696}696}
697697
698TEST_F(BufferQueueTest, callbacks_cant_happen_after_shutdown)
699{
700 mc::BufferQueue q(1, allocator, basic_properties, policy_factory);
701
702 q.drop_client_requests();
703 auto client = client_acquire_async(q);
704 ASSERT_FALSE(client->has_acquired_buffer());
705}
706
707TEST_F(BufferQueueTest, callbacks_cant_happen_after_shutdown_with_snapshots)
708{
709 mc::BufferQueue q(1, allocator, basic_properties, policy_factory);
710
711 auto snapshot = q.snapshot_acquire();
712 q.drop_client_requests();
713 q.snapshot_release(snapshot);
714
715 auto client = client_acquire_async(q);
716 ASSERT_FALSE(client->has_acquired_buffer());
717}
718
698TEST_F(BufferQueueTest, snapshot_acquire_never_blocks)719TEST_F(BufferQueueTest, snapshot_acquire_never_blocks)
699{720{
700 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)721 for (int nbuffers = 1; nbuffers <= max_nbuffers_to_test; ++nbuffers)

Subscribers

People subscribed via source and target branches

to all changes: