Mir

Merge lp:~alan-griffiths/mir/draft-surfaces-report into lp:mir

Proposed by Alan Griffiths
Status: Merged
Merged at revision: 1162
Proposed branch: lp:~alan-griffiths/mir/draft-surfaces-report
Merge into: lp:mir
Diff against target: 283 lines (+215/-0)
5 files modified
src/server/surfaces/CMakeLists.txt (+1/-0)
src/server/surfaces/surface.cpp (+4/-0)
src/server/surfaces/surface_stack.cpp (+5/-0)
src/server/surfaces/surfaces_report.cpp (+154/-0)
src/server/surfaces/surfaces_report.h (+51/-0)
To merge this branch: bzr merge lp:~alan-griffiths/mir/draft-surfaces-report
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Needs Fixing
Robert Carr (community) Approve
Daniel van Vugt Abstain
Alexandros Frantzis (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+191215@code.launchpad.net

Commit message

surface: draft debugging report to track surface management issues

Description of the change

surface: draft debugging report to track surface management issues

This checks an environment variable (MIR_DEBUG_SURFACES_REPORT) for the value "debug" and, if it finds that value dumps some debug information about surface management to stdout. It looks like:

DebugSurfacesReport::surface_created(0x7fece8000e58 ["eglappsurface"])
DebugSurfacesReport::create_surface_call(0x7fece8000e58 ["eglappsurface"]) - INFO surface count=1
DebugSurfacesReport::surface_created(0x7fecdc0011e8 ["eglappsurface"])
DebugSurfacesReport::create_surface_call(0x7fecdc0011e8 ["eglappsurface"]) - INFO surface count=2
DebugSurfacesReport::delete_surface_call(0x7fece8000e58 ["eglappsurface"]) - INFO surface count=2
DebugSurfacesReport::surface_deleted(0x7fece8000e58 ["eglappsurface"]) - INFO surface count=1
DebugSurfacesReport::delete_surface_call(0x7fecdc0011e8 ["eglappsurface"]) - INFO surface count=1
DebugSurfacesReport::surface_deleted(0x7fecdc0011e8 ["eglappsurface"]) - INFO surface count=0

This allows for checking that surfaces are not owned outside the surface stack. If that is happening then delete_surface_calls will not be followed by surface_deleted() calls and the surface count will not be decremented.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

OK for the purpose of debugging this particular problem, but also +1 for SurfacesReport gradually evolving to a configurable, publicly accessible report, like the other reports we have in the code.

I find SurfacesReport::create_surface_call() being called after SurfacesReport::surface_created() a bit unintuitive without knowledge of the internals (I would expect the opposite order). Perhaps we could find a more descriptive name for the *_call() methods, but not a blocker at this point.

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

From what I can see, this does not affect our ability to move around and clean up the many /Surface/ classes post saucy. So that's good. But then, I still don't support the idea of reports being classes at all.

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

Ok for now.

review: Approve
Revision history for this message
Kevin DuBois (kdub) wrote :

l135, why use getenv instead of using the options that we already have? i'd like to avoid too much split between env and command line variables.

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/server/surfaces/CMakeLists.txt'
2--- src/server/surfaces/CMakeLists.txt 2013-08-28 03:41:48 +0000
3+++ src/server/surfaces/CMakeLists.txt 2013-10-15 14:45:43 +0000
4@@ -6,4 +6,5 @@
5 surface_data.cpp
6 surface_stack.cpp
7 surface_controller.cpp
8+ surfaces_report.cpp
9 )
10
11=== modified file 'src/server/surfaces/surface.cpp'
12--- src/server/surfaces/surface.cpp 2013-10-03 06:01:11 +0000
13+++ src/server/surfaces/surface.cpp 2013-10-15 14:45:43 +0000
14@@ -24,6 +24,8 @@
15 #include "mir/input/input_channel.h"
16 #include "mir/graphics/buffer.h"
17
18+#include "surfaces_report.h"
19+
20 #include <boost/throw_exception.hpp>
21
22 #include <stdexcept>
23@@ -43,6 +45,7 @@
24 server_input_channel(input_channel),
25 surface_in_startup(true)
26 {
27+ the_surfaces_report()->surface_created(this);
28 }
29
30 void ms::Surface::force_requests_to_complete()
31@@ -52,6 +55,7 @@
32
33 ms::Surface::~Surface()
34 {
35+ the_surfaces_report()->surface_deleted(this);
36 }
37
38 std::shared_ptr<ms::BufferStream> ms::Surface::buffer_stream() const
39
40=== modified file 'src/server/surfaces/surface_stack.cpp'
41--- src/server/surfaces/surface_stack.cpp 2013-10-03 06:01:11 +0000
42+++ src/server/surfaces/surface_stack.cpp 2013-10-15 14:45:43 +0000
43@@ -29,6 +29,8 @@
44 #include "mir/surfaces/input_registrar.h"
45 #include "mir/input/input_channel_factory.h"
46
47+#include "surfaces_report.h"
48+
49 #include <boost/throw_exception.hpp>
50
51 #include <algorithm>
52@@ -84,6 +86,7 @@
53
54 input_registrar->input_channel_opened(surface->input_channel(), surface->input_surface(), params.input_mode);
55
56+ the_surfaces_report()->create_surface_call(surface.get());
57 emit_change_notification();
58
59 return surface;
60@@ -92,6 +95,8 @@
61 void ms::SurfaceStack::destroy_surface(std::weak_ptr<ms::Surface> const& surface)
62 {
63 auto keep_alive = surface.lock();
64+ the_surfaces_report()->delete_surface_call(keep_alive.get());
65+
66 bool found_surface = false;
67 {
68 std::lock_guard<std::recursive_mutex> lg(guard);
69
70=== added file 'src/server/surfaces/surfaces_report.cpp'
71--- src/server/surfaces/surfaces_report.cpp 1970-01-01 00:00:00 +0000
72+++ src/server/surfaces/surfaces_report.cpp 2013-10-15 14:45:43 +0000
73@@ -0,0 +1,154 @@
74+/*
75+ * Copyright © 2013 Canonical Ltd.
76+ *
77+ * This program is free software: you can redistribute it and/or modify it
78+ * under the terms of the GNU General Public License version 3,
79+ * as published by the Free Software Foundation.
80+ *
81+ * This program is distributed in the hope that it will be useful,
82+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
83+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84+ * GNU General Public License for more details.
85+ *
86+ * You should have received a copy of the GNU General Public License
87+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
88+ *
89+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
90+ */
91+
92+#include "surfaces_report.h"
93+
94+#include "mir/surfaces/surface.h"
95+
96+#include <cstdlib>
97+#include <cstring>
98+
99+#include <iostream>
100+#include <map>
101+#include <memory>
102+#include <mutex>
103+
104+namespace ms = mir::surfaces;
105+
106+namespace
107+{
108+class NullSurfacesReport : public ms::SurfacesReport
109+{
110+public:
111+ virtual void surface_created(ms::Surface* const /*surface*/) {}
112+ virtual void create_surface_call(ms::Surface* const /*surface*/) {}
113+
114+ virtual void delete_surface_call(ms::Surface* const /*surface*/) {}
115+ virtual void surface_deleted(ms::Surface* const /*surface*/) {}
116+};
117+
118+class DebugSurfacesReport : public ms::SurfacesReport
119+{
120+public:
121+ virtual void surface_created(ms::Surface* const /*surface*/);
122+ virtual void create_surface_call(ms::Surface* const /*surface*/);
123+
124+ virtual void delete_surface_call(ms::Surface* const /*surface*/);
125+ virtual void surface_deleted(ms::Surface* const /*surface*/);
126+
127+private:
128+ std::mutex mutable mutex;
129+
130+ std::map<ms::Surface*, std::string> surfaces;
131+};
132+
133+bool is_debug()
134+{
135+ auto env = std::getenv("MIR_DEBUG_SURFACES_REPORT");
136+ return env && !std::strcmp(env, "debug");
137+}
138+}
139+
140+
141+void DebugSurfacesReport::surface_created(ms::Surface* const surface)
142+{
143+ std::lock_guard<std::mutex> lock(mutex);
144+ surfaces[surface] = surface->name();
145+
146+ std::cout << "DebugSurfacesReport::surface_created(" <<
147+ surface << " [\"" << surface->name() << "\"])" << std::endl;
148+}
149+
150+void DebugSurfacesReport::create_surface_call(ms::Surface* const surface)
151+{
152+ std::lock_guard<std::mutex> lock(mutex);
153+
154+ auto const i = surfaces.find(surface);
155+
156+ std::cout << "DebugSurfacesReport::create_surface_call(" <<
157+ surface << " [\"" << surface->name() << "\"])";
158+
159+ if (i == surfaces.end())
160+ {
161+ std::cout << " - ERROR not reported to surface_created()";
162+ }
163+ else if (surface->name() != i->second)
164+ {
165+ std::cout << " - WARNING name changed from " << i->second;
166+ }
167+
168+ std::cout << " - INFO surface count=" << surfaces.size() << std::endl;
169+}
170+
171+void DebugSurfacesReport::delete_surface_call(ms::Surface* const surface)
172+{
173+ std::lock_guard<std::mutex> lock(mutex);
174+
175+ auto const i = surfaces.find(surface);
176+
177+ std::cout << "DebugSurfacesReport::delete_surface_call(" <<
178+ surface << " [\"" << surface->name() << "\"])";
179+
180+ if (i == surfaces.end())
181+ {
182+ std::cout << " - ERROR not reported to surface_created()";
183+ }
184+ else if (surface->name() != i->second)
185+ {
186+ std::cout << " - WARNING name changed from " << i->second;
187+ }
188+
189+ std::cout << " - INFO surface count=" << surfaces.size() << std::endl;
190+}
191+
192+void DebugSurfacesReport::surface_deleted(ms::Surface* const surface)
193+{
194+ std::lock_guard<std::mutex> lock(mutex);
195+
196+ auto const i = surfaces.find(surface);
197+
198+ std::cout << "DebugSurfacesReport::surface_deleted(" <<
199+ surface << " [\"" << surface->name() << "\"])";
200+
201+ if (i == surfaces.end())
202+ {
203+ std::cout << " - ERROR not reported to surface_created()";
204+ }
205+ else if (surface->name() != i->second)
206+ {
207+ std::cout << " - WARNING name changed from " << i->second;
208+ }
209+
210+ if (i != surfaces.end())
211+ surfaces.erase(i);
212+
213+ std::cout << " - INFO surface count=" << surfaces.size() << std::endl;
214+}
215+
216+ms::SurfacesReport* ms::the_surfaces_report()
217+{
218+ static auto const result =
219+ is_debug() ?
220+ std::shared_ptr<ms::SurfacesReport>(std::make_shared<DebugSurfacesReport>()) :
221+ std::shared_ptr<ms::SurfacesReport>(std::make_shared<NullSurfacesReport>());
222+
223+ return result.get();
224+}
225+
226+
227+
228
229=== added file 'src/server/surfaces/surfaces_report.h'
230--- src/server/surfaces/surfaces_report.h 1970-01-01 00:00:00 +0000
231+++ src/server/surfaces/surfaces_report.h 2013-10-15 14:45:43 +0000
232@@ -0,0 +1,51 @@
233+/*
234+ * Copyright © 2013 Canonical Ltd.
235+ *
236+ * This program is free software: you can redistribute it and/or modify it
237+ * under the terms of the GNU General Public License version 3,
238+ * as published by the Free Software Foundation.
239+ *
240+ * This program is distributed in the hope that it will be useful,
241+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
242+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
243+ * GNU General Public License for more details.
244+ *
245+ * You should have received a copy of the GNU General Public License
246+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
247+ *
248+ * Authored by: Alan Griffiths <alan@octopull.co.uk>
249+ */
250+
251+
252+#ifndef MIR_SURFACES_SURFACES_REPORT_H_
253+#define MIR_SURFACES_SURFACES_REPORT_H_
254+
255+namespace mir
256+{
257+namespace surfaces
258+{
259+class Surface;
260+
261+class SurfacesReport
262+{
263+public:
264+ virtual void surface_created(Surface* const surface) = 0;
265+ virtual void create_surface_call(Surface* const surface) = 0;
266+
267+ virtual void delete_surface_call(Surface* const surface) = 0;
268+ virtual void surface_deleted(Surface* const surface) = 0;
269+
270+protected:
271+ SurfacesReport() = default;
272+ virtual ~SurfacesReport() = default;
273+ SurfacesReport(SurfacesReport const&) = delete;
274+ SurfacesReport& operator=(SurfacesReport const&) = delete;
275+};
276+
277+// For the moment this is a debugging frig - it should probably grow into a real PfA report
278+SurfacesReport* the_surfaces_report();
279+}
280+}
281+
282+
283+#endif /* MIR_SURFACES_SURFACES_REPORT_H_ */

Subscribers

People subscribed via source and target branches