]> granicus.if.org Git - icinga2/blob - doc/21-development.md
c60292c3ec63eae0e8743b332edc169da962df76
[icinga2] / doc / 21-development.md
1 # <a id="development"></a> Develop Icinga 2
2
3 This chapter provides hints on Icinga 2 development
4 especially for debugging purposes.
5
6 > **Note**
7 >
8 > If you are planning to build your own development environment,
9 > please consult the `INSTALL.md` file from the source tree.
10
11 ## <a id="debug-requirements"></a> Debug Requirements
12
13 Make sure that the debug symbols are available for Icinga 2.
14 The Icinga 2 packages provide a debug package which must be
15 installed separately for all involved binaries, like `icinga2-bin`
16 or `icinga2-ido-mysql`.
17
18 Debian/Ubuntu:
19
20     # apt-get install icinga2-dbg
21
22 RHEL/CentOS:
23
24     # yum install icinga2-debuginfo
25
26 SLES/openSUSE:
27
28     # zypper install icinga2-bin-debuginfo icinga2-ido-mysql-debuginfo
29
30
31 Furthermore, you may also have to install debug symbols for Boost and your C library.
32
33 If you're building your own binaries, you should use the `-DCMAKE_BUILD_TYPE=Debug` cmake
34 build flag for debug builds.
35
36
37 ## <a id="development-debug-gdb"></a> GDB
38
39 Install gdb:
40
41 Debian/Ubuntu:
42
43     # apt-get install gdb
44
45 RHEL/CentOS/Fedora:
46
47     # yum install gdb
48
49 SLES/openSUSE:
50
51     # zypper install gdb
52
53
54 Install the `boost`, `python` and `icinga2` pretty printers. Absolute paths are required,
55 so please make sure to update the installation paths accordingly (`pwd`).
56
57     $ mkdir -p ~/.gdb_printers && cd ~/.gdb_printers
58
59 Boost Pretty Printers compatible with Python 3:
60
61     $ git clone https://github.com/mateidavid/Boost-Pretty-Printer.git && cd Boost-Pretty-Printer
62     $ git checkout python-3
63     $ pwd
64     /home/michi/.gdb_printers/Boost-Pretty-Printer
65
66 Python Pretty Printers:
67
68     $ cd ~/.gdb_printers
69     $ svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python
70
71 Icinga 2 Pretty Printers:
72
73     $ mkdir -p ~/.gdb_printers/icinga2 && cd ~/.gdb_printers/icinga2
74     $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/icingadbg.py
75
76 Now you'll need to modify/setup your `~/.gdbinit` configuration file.
77 You can download the one from Icinga 2 and modify all paths.
78
79 Example on Fedora 22:
80
81     $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/gdbinit -O ~/.gdbinit
82     $ vim ~/.gdbinit
83
84     set print pretty on
85     
86     python
87     import sys
88     sys.path.insert(0, '/home/michi/.gdb_printers/icinga2')
89     from icingadbg import register_icinga_printers
90     register_icinga_printers()
91     end
92     
93     python
94     import sys
95     sys.path.insert(0, '/home/michi/.gdb_printers/python')
96     from libstdcxx.v6.printers import register_libstdcxx_printers
97     try:
98         register_libstdcxx_printers(None)
99     except:
100         pass
101     end
102     
103     python
104     import sys
105     sys.path.insert(0, '/home/michi/.gdb_printers/Boost-Pretty-Printer')
106     import boost_print
107     boost_print.register_printers()
108     end
109
110
111 If you are getting the following error when running gdb, the `libstdcxx`
112 printers are already preloaded in your environment and you can remove
113 the duplicate import in your `~/.gdbinit` file.
114
115     RuntimeError: pretty-printer already registered: libstdc++-v6
116
117 ### <a id="development-debug-gdb-run"></a> GDB Run
118
119 Call GDB with the binary (`/usr/sbin/icinga2` is a wrapper script calling
120 `/usr/lib64/icinga2/sbin/icinga2` since 2.4) and all arguments and run it in foreground.
121 If VFork causes trouble, disable it inside the gdb run.
122
123     # gdb --args /usr/lib64/icinga2/sbin/icinga2 daemon -x debug -DUseVfork=0
124
125 The exact path to the Icinga 2 binary differs on each distribution. On Ubuntu
126 it is installed into `/usr/lib/x86_64-linux-gnu/icinga2/sbin/icinga2` on 64-bit systems
127 for example.
128
129 > **Note**
130 >
131 > If gdb tells you it's missing debug symbols, quit gdb and install
132 > them: `Missing separate debuginfos, use: debuginfo-install ...`
133
134 Run the application.
135
136     (gdb) r
137
138 Kill the running application.
139
140     (gdb) k
141
142 Continue after breakpoint.
143
144     (gdb) c
145
146 ### <a id="development-debug-gdb-coredump"></a> GDB Core Dump
147
148 Either attach to the running process using `gdb -p PID` or start
149 a new gdb run.
150
151     (gdb) r
152     (gdb) generate-core-file
153
154 ### <a id="development-debug-gdb-backtrace"></a> GDB Backtrace
155
156 If Icinga 2 aborted its operation abnormally, generate a backtrace.
157
158     (gdb) bt
159     (gdb) thread apply all bt full
160
161 If Icinga 2 is still running, generate a full backtrace from the running
162 process and store it into a new file (e.g. for debugging dead locks):
163
164     # gdb -p $(pidof icinga2) -batch -ex "thread apply all bt full" -ex "detach" -ex "q" > gdb_bt.log
165
166 If you're opening an issue at [https://dev.icinga.org], make sure
167 to attach as much detail as possible.
168
169 ### <a id="development-debug-gdb-backtrace-stepping"></a> GDB Backtrace Stepping
170
171 Identifying the problem may require stepping into the backtrace, analysing
172 the current scope, attributes, and possible unmet requirements. `p` prints
173 the value of the selected variable or function call result.
174
175     (gdb) up
176     (gdb) down
177     (gdb) p checkable
178     (gdb) p checkable.px->m_Name
179
180
181 ### <a id="development-debug-gdb-breakpoint"></a> GDB Breakpoints
182
183 To set a breakpoint to a specific function call, or file specific line.
184
185     (gdb) b checkable.cpp:125
186     (gdb) b icinga::Checkable::SetEnablePerfdata
187
188 GDB will ask about loading the required symbols later, select `yes` instead
189 of `no`.
190
191 Then run Icinga 2 until it reaches the first breakpoint. Continue with `c`
192 afterwards.
193
194     (gdb) run
195     (gdb) c
196
197 If you want to delete all breakpoints, use `d` and select `yes`.
198
199     (gdb) d
200
201 > **Tip**
202 >
203 > When debugging exceptions, set your breakpoint like this: `b __cxa_throw`.
204
205 Breakpoint Example:
206
207     (gdb) b __cxa_throw
208     (gdb) r
209     (gdb) up
210     ....
211     (gdb) up
212     #11 0x00007ffff7cbf9ff in icinga::Utility::GlobRecursive(icinga::String const&, icinga::String const&, boost::function<void (icinga::String const&)> const&, int) (path=..., pattern=..., callback=..., type=1)
213         at /home/michi/coding/icinga/icinga2/lib/base/utility.cpp:609
214     609                 callback(cpath);
215     (gdb) l
216     604
217     605 #endif /* _WIN32 */
218     606
219     607         std::sort(files.begin(), files.end());
220     608         BOOST_FOREACH(const String& cpath, files) {
221     609                 callback(cpath);
222     610         }
223     611
224     612         std::sort(dirs.begin(), dirs.end());
225     613         BOOST_FOREACH(const String& cpath, dirs) {
226     (gdb) p files
227     $3 = std::vector of length 11, capacity 16 = {{static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/agent.conf"}, {static NPos = 18446744073709551615,
228         m_Data = "/etc/icinga2/conf.d/commands.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/downtimes.conf"}, {static NPos = 18446744073709551615,
229         m_Data = "/etc/icinga2/conf.d/groups.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/notifications.conf"}, {static NPos = 18446744073709551615,
230         m_Data = "/etc/icinga2/conf.d/satellite.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/services.conf"}, {static NPos = 18446744073709551615,
231         m_Data = "/etc/icinga2/conf.d/templates.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/test.conf"}, {static NPos = 18446744073709551615,
232         m_Data = "/etc/icinga2/conf.d/timeperiods.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/users.conf"}}