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
=== modified file 'src/server/surfaces/CMakeLists.txt'
--- src/server/surfaces/CMakeLists.txt 2013-08-28 03:41:48 +0000
+++ src/server/surfaces/CMakeLists.txt 2013-10-15 14:45:43 +0000
@@ -6,4 +6,5 @@
6 surface_data.cpp6 surface_data.cpp
7 surface_stack.cpp7 surface_stack.cpp
8 surface_controller.cpp8 surface_controller.cpp
9 surfaces_report.cpp
9)10)
1011
=== modified file 'src/server/surfaces/surface.cpp'
--- src/server/surfaces/surface.cpp 2013-10-03 06:01:11 +0000
+++ src/server/surfaces/surface.cpp 2013-10-15 14:45:43 +0000
@@ -24,6 +24,8 @@
24#include "mir/input/input_channel.h"24#include "mir/input/input_channel.h"
25#include "mir/graphics/buffer.h"25#include "mir/graphics/buffer.h"
2626
27#include "surfaces_report.h"
28
27#include <boost/throw_exception.hpp>29#include <boost/throw_exception.hpp>
2830
29#include <stdexcept>31#include <stdexcept>
@@ -43,6 +45,7 @@
43 server_input_channel(input_channel),45 server_input_channel(input_channel),
44 surface_in_startup(true)46 surface_in_startup(true)
45{47{
48 the_surfaces_report()->surface_created(this);
46}49}
4750
48void ms::Surface::force_requests_to_complete()51void ms::Surface::force_requests_to_complete()
@@ -52,6 +55,7 @@
5255
53ms::Surface::~Surface()56ms::Surface::~Surface()
54{57{
58 the_surfaces_report()->surface_deleted(this);
55}59}
5660
57std::shared_ptr<ms::BufferStream> ms::Surface::buffer_stream() const61std::shared_ptr<ms::BufferStream> ms::Surface::buffer_stream() const
5862
=== modified file 'src/server/surfaces/surface_stack.cpp'
--- src/server/surfaces/surface_stack.cpp 2013-10-03 06:01:11 +0000
+++ src/server/surfaces/surface_stack.cpp 2013-10-15 14:45:43 +0000
@@ -29,6 +29,8 @@
29#include "mir/surfaces/input_registrar.h"29#include "mir/surfaces/input_registrar.h"
30#include "mir/input/input_channel_factory.h"30#include "mir/input/input_channel_factory.h"
3131
32#include "surfaces_report.h"
33
32#include <boost/throw_exception.hpp>34#include <boost/throw_exception.hpp>
3335
34#include <algorithm>36#include <algorithm>
@@ -84,6 +86,7 @@
8486
85 input_registrar->input_channel_opened(surface->input_channel(), surface->input_surface(), params.input_mode);87 input_registrar->input_channel_opened(surface->input_channel(), surface->input_surface(), params.input_mode);
8688
89 the_surfaces_report()->create_surface_call(surface.get());
87 emit_change_notification();90 emit_change_notification();
8891
89 return surface;92 return surface;
@@ -92,6 +95,8 @@
92void ms::SurfaceStack::destroy_surface(std::weak_ptr<ms::Surface> const& surface)95void ms::SurfaceStack::destroy_surface(std::weak_ptr<ms::Surface> const& surface)
93{96{
94 auto keep_alive = surface.lock();97 auto keep_alive = surface.lock();
98 the_surfaces_report()->delete_surface_call(keep_alive.get());
99
95 bool found_surface = false;100 bool found_surface = false;
96 {101 {
97 std::lock_guard<std::recursive_mutex> lg(guard);102 std::lock_guard<std::recursive_mutex> lg(guard);
98103
=== added file 'src/server/surfaces/surfaces_report.cpp'
--- src/server/surfaces/surfaces_report.cpp 1970-01-01 00:00:00 +0000
+++ src/server/surfaces/surfaces_report.cpp 2013-10-15 14:45:43 +0000
@@ -0,0 +1,154 @@
1/*
2 * Copyright © 2013 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 "surfaces_report.h"
20
21#include "mir/surfaces/surface.h"
22
23#include <cstdlib>
24#include <cstring>
25
26#include <iostream>
27#include <map>
28#include <memory>
29#include <mutex>
30
31namespace ms = mir::surfaces;
32
33namespace
34{
35class NullSurfacesReport : public ms::SurfacesReport
36{
37public:
38 virtual void surface_created(ms::Surface* const /*surface*/) {}
39 virtual void create_surface_call(ms::Surface* const /*surface*/) {}
40
41 virtual void delete_surface_call(ms::Surface* const /*surface*/) {}
42 virtual void surface_deleted(ms::Surface* const /*surface*/) {}
43};
44
45class DebugSurfacesReport : public ms::SurfacesReport
46{
47public:
48 virtual void surface_created(ms::Surface* const /*surface*/);
49 virtual void create_surface_call(ms::Surface* const /*surface*/);
50
51 virtual void delete_surface_call(ms::Surface* const /*surface*/);
52 virtual void surface_deleted(ms::Surface* const /*surface*/);
53
54private:
55 std::mutex mutable mutex;
56
57 std::map<ms::Surface*, std::string> surfaces;
58};
59
60bool is_debug()
61{
62 auto env = std::getenv("MIR_DEBUG_SURFACES_REPORT");
63 return env && !std::strcmp(env, "debug");
64}
65}
66
67
68void DebugSurfacesReport::surface_created(ms::Surface* const surface)
69{
70 std::lock_guard<std::mutex> lock(mutex);
71 surfaces[surface] = surface->name();
72
73 std::cout << "DebugSurfacesReport::surface_created(" <<
74 surface << " [\"" << surface->name() << "\"])" << std::endl;
75}
76
77void DebugSurfacesReport::create_surface_call(ms::Surface* const surface)
78{
79 std::lock_guard<std::mutex> lock(mutex);
80
81 auto const i = surfaces.find(surface);
82
83 std::cout << "DebugSurfacesReport::create_surface_call(" <<
84 surface << " [\"" << surface->name() << "\"])";
85
86 if (i == surfaces.end())
87 {
88 std::cout << " - ERROR not reported to surface_created()";
89 }
90 else if (surface->name() != i->second)
91 {
92 std::cout << " - WARNING name changed from " << i->second;
93 }
94
95 std::cout << " - INFO surface count=" << surfaces.size() << std::endl;
96}
97
98void DebugSurfacesReport::delete_surface_call(ms::Surface* const surface)
99{
100 std::lock_guard<std::mutex> lock(mutex);
101
102 auto const i = surfaces.find(surface);
103
104 std::cout << "DebugSurfacesReport::delete_surface_call(" <<
105 surface << " [\"" << surface->name() << "\"])";
106
107 if (i == surfaces.end())
108 {
109 std::cout << " - ERROR not reported to surface_created()";
110 }
111 else if (surface->name() != i->second)
112 {
113 std::cout << " - WARNING name changed from " << i->second;
114 }
115
116 std::cout << " - INFO surface count=" << surfaces.size() << std::endl;
117}
118
119void DebugSurfacesReport::surface_deleted(ms::Surface* const surface)
120{
121 std::lock_guard<std::mutex> lock(mutex);
122
123 auto const i = surfaces.find(surface);
124
125 std::cout << "DebugSurfacesReport::surface_deleted(" <<
126 surface << " [\"" << surface->name() << "\"])";
127
128 if (i == surfaces.end())
129 {
130 std::cout << " - ERROR not reported to surface_created()";
131 }
132 else if (surface->name() != i->second)
133 {
134 std::cout << " - WARNING name changed from " << i->second;
135 }
136
137 if (i != surfaces.end())
138 surfaces.erase(i);
139
140 std::cout << " - INFO surface count=" << surfaces.size() << std::endl;
141}
142
143ms::SurfacesReport* ms::the_surfaces_report()
144{
145 static auto const result =
146 is_debug() ?
147 std::shared_ptr<ms::SurfacesReport>(std::make_shared<DebugSurfacesReport>()) :
148 std::shared_ptr<ms::SurfacesReport>(std::make_shared<NullSurfacesReport>());
149
150 return result.get();
151}
152
153
154
0155
=== added file 'src/server/surfaces/surfaces_report.h'
--- src/server/surfaces/surfaces_report.h 1970-01-01 00:00:00 +0000
+++ src/server/surfaces/surfaces_report.h 2013-10-15 14:45:43 +0000
@@ -0,0 +1,51 @@
1/*
2 * Copyright © 2013 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
20#ifndef MIR_SURFACES_SURFACES_REPORT_H_
21#define MIR_SURFACES_SURFACES_REPORT_H_
22
23namespace mir
24{
25namespace surfaces
26{
27class Surface;
28
29class SurfacesReport
30{
31public:
32 virtual void surface_created(Surface* const surface) = 0;
33 virtual void create_surface_call(Surface* const surface) = 0;
34
35 virtual void delete_surface_call(Surface* const surface) = 0;
36 virtual void surface_deleted(Surface* const surface) = 0;
37
38protected:
39 SurfacesReport() = default;
40 virtual ~SurfacesReport() = default;
41 SurfacesReport(SurfacesReport const&) = delete;
42 SurfacesReport& operator=(SurfacesReport const&) = delete;
43};
44
45// For the moment this is a debugging frig - it should probably grow into a real PfA report
46SurfacesReport* the_surfaces_report();
47}
48}
49
50
51#endif /* MIR_SURFACES_SURFACES_REPORT_H_ */

Subscribers

People subscribed via source and target branches