]> granicus.if.org Git - icinga2/blob - doc/21-development.md
Merge pull request #6503 from peteeckel/fix/reduce-loglevel-plugin-env-6460
[icinga2] / doc / 21-development.md
1 # Develop Icinga 2 <a id="development"></a>
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 ## Debug Requirements <a id="debug-requirements"></a>
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 Fedora:
27
28     # dnf install icinga2-debuginfo icinga2-bin-debuginfo icinga2-ido-mysql-debuginfo
29
30 SLES/openSUSE:
31
32     # zypper install icinga2-bin-debuginfo icinga2-ido-mysql-debuginfo
33
34
35 Furthermore, you may also have to install debug symbols for Boost and your C library.
36
37 If you're building your own binaries, you should use the `-DCMAKE_BUILD_TYPE=Debug` cmake
38 build flag for debug builds.
39
40
41 ## GDB <a id="development-debug-gdb"></a>
42
43 Install gdb:
44
45 Debian/Ubuntu:
46
47     # apt-get install gdb
48
49 RHEL/CentOS/Fedora:
50
51     # yum install gdb
52
53 SLES/openSUSE:
54
55     # zypper install gdb
56
57
58 Install the `boost`, `python` and `icinga2` pretty printers. Absolute paths are required,
59 so please make sure to update the installation paths accordingly (`pwd`).
60
61     $ mkdir -p ~/.gdb_printers && cd ~/.gdb_printers
62
63 Boost Pretty Printers compatible with Python 3:
64
65     $ git clone https://github.com/mateidavid/Boost-Pretty-Printer.git && cd Boost-Pretty-Printer
66     $ git checkout python-3
67     $ pwd
68     /home/michi/.gdb_printers/Boost-Pretty-Printer
69
70 Python Pretty Printers:
71
72     $ cd ~/.gdb_printers
73     $ svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python
74
75 Icinga 2 Pretty Printers:
76
77     $ mkdir -p ~/.gdb_printers/icinga2 && cd ~/.gdb_printers/icinga2
78     $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/icingadbg.py
79
80 Now you'll need to modify/setup your `~/.gdbinit` configuration file.
81 You can download the one from Icinga 2 and modify all paths.
82
83 Example on Fedora 22:
84
85     $ wget https://raw.githubusercontent.com/Icinga/icinga2/master/tools/debug/gdb/gdbinit -O ~/.gdbinit
86     $ vim ~/.gdbinit
87
88     set print pretty on
89     
90     python
91     import sys
92     sys.path.insert(0, '/home/michi/.gdb_printers/icinga2')
93     from icingadbg import register_icinga_printers
94     register_icinga_printers()
95     end
96     
97     python
98     import sys
99     sys.path.insert(0, '/home/michi/.gdb_printers/python')
100     from libstdcxx.v6.printers import register_libstdcxx_printers
101     try:
102         register_libstdcxx_printers(None)
103     except:
104         pass
105     end
106     
107     python
108     import sys
109     sys.path.insert(0, '/home/michi/.gdb_printers/Boost-Pretty-Printer')
110     import boost_print
111     boost_print.register_printers()
112     end
113
114
115 If you are getting the following error when running gdb, the `libstdcxx`
116 printers are already preloaded in your environment and you can remove
117 the duplicate import in your `~/.gdbinit` file.
118
119     RuntimeError: pretty-printer already registered: libstdc++-v6
120
121 ### GDB Run <a id="development-debug-gdb-run"></a>
122
123 Call GDB with the binary (`/usr/sbin/icinga2` is a wrapper script calling
124 `/usr/lib64/icinga2/sbin/icinga2` since 2.4) and all arguments and run it in foreground.
125
126     # gdb --args /usr/lib64/icinga2/sbin/icinga2 daemon -x debug --no-stack-rlimit
127
128 The exact path to the Icinga 2 binary differs on each distribution. On Ubuntu
129 it is installed into `/usr/lib/x86_64-linux-gnu/icinga2/sbin/icinga2` on 64-bit systems
130 for example.
131
132 > **Note**
133 >
134 > If gdb tells you it's missing debug symbols, quit gdb and install
135 > them: `Missing separate debuginfos, use: debuginfo-install ...`
136
137 Run the application.
138
139     (gdb) r
140
141 Kill the running application.
142
143     (gdb) k
144
145 Continue after breakpoint.
146
147     (gdb) c
148
149 ### GDB Core Dump <a id="development-debug-gdb-coredump"></a>
150
151 Either attach to the running process using `gdb -p PID` or start
152 a new gdb run.
153
154     (gdb) r
155     (gdb) generate-core-file
156
157 ### GDB Backtrace <a id="development-debug-gdb-backtrace"></a>
158
159 If Icinga 2 aborted its operation abnormally, generate a backtrace.
160
161     (gdb) bt
162     (gdb) thread apply all bt full
163
164 If gdb stops at a SIGPIPE signal please disable the signal before
165 running Icinga 2.
166
167     (gdb) handle SIGPIPE nostop noprint pass
168     (gdb) r
169
170 If you create a [bug report](https://www.icinga.com/community/get-involved/),
171 make sure to attach as much detail as possible.
172
173 ### GDB Backtrace from Running Process <a id="development-debug-gdb-backtrace-running"></a>
174
175 If Icinga 2 is still running, generate a full backtrace from the running
176 process and store it into a new file (e.g. for debugging dead locks):
177
178 Icinga 2 runs with 2 processes, therefore generate two backtrace logs
179 and add them to the GitHub issue.
180
181 ```
182 for pid in $(pidof icinga2); do gdb -p $pid -batch -ex "thread apply all bt full" -ex "detach" -ex "q" > gdb_bt_${pid}_`date +%s`.log; done
183 ```
184
185 ### GDB Thread List from Running Process <a id="development-debug-gdb-thread-list-running"></a>
186
187 Instead of a full backtrace, you sometimes just need a list of running threads.
188
189 ```
190 for pid in $(pidof icinga2); do gdb -p $pid -batch -ex "info threads" -ex "detach" -ex "q" > gdb_threads_${pid}_`date +%s`.log; done
191 ```
192
193 ### GDB Backtrace Stepping <a id="development-debug-gdb-backtrace-stepping"></a>
194
195 Identifying the problem may require stepping into the backtrace, analysing
196 the current scope, attributes, and possible unmet requirements. `p` prints
197 the value of the selected variable or function call result.
198
199     (gdb) up
200     (gdb) down
201     (gdb) p checkable
202     (gdb) p checkable.px->m_Name
203
204
205 ### GDB Breakpoints <a id="development-debug-gdb-breakpoint"></a>
206
207 To set a breakpoint to a specific function call, or file specific line.
208
209     (gdb) b checkable.cpp:125
210     (gdb) b icinga::Checkable::SetEnablePerfdata
211
212 GDB will ask about loading the required symbols later, select `yes` instead
213 of `no`.
214
215 Then run Icinga 2 until it reaches the first breakpoint. Continue with `c`
216 afterwards.
217
218     (gdb) run
219     (gdb) c
220
221 If you want to delete all breakpoints, use `d` and select `yes`.
222
223     (gdb) d
224
225 > **Tip**
226 >
227 > When debugging exceptions, set your breakpoint like this: `b __cxa_throw`.
228
229 Breakpoint Example:
230
231     (gdb) b __cxa_throw
232     (gdb) r
233     (gdb) up
234     ....
235     (gdb) up
236     #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)
237         at /home/michi/coding/icinga/icinga2/lib/base/utility.cpp:609
238     609                 callback(cpath);
239     (gdb) l
240     604
241     605 #endif /* _WIN32 */
242     606
243     607         std::sort(files.begin(), files.end());
244     608         BOOST_FOREACH(const String& cpath, files) {
245     609                 callback(cpath);
246     610         }
247     611
248     612         std::sort(dirs.begin(), dirs.end());
249     613         BOOST_FOREACH(const String& cpath, dirs) {
250     (gdb) p files
251     $3 = std::vector of length 11, capacity 16 = {{static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/agent.conf"}, {static NPos = 18446744073709551615,
252         m_Data = "/etc/icinga2/conf.d/commands.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/downtimes.conf"}, {static NPos = 18446744073709551615,
253         m_Data = "/etc/icinga2/conf.d/groups.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/notifications.conf"}, {static NPos = 18446744073709551615,
254         m_Data = "/etc/icinga2/conf.d/satellite.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/services.conf"}, {static NPos = 18446744073709551615,
255         m_Data = "/etc/icinga2/conf.d/templates.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/test.conf"}, {static NPos = 18446744073709551615,
256         m_Data = "/etc/icinga2/conf.d/timeperiods.conf"}, {static NPos = 18446744073709551615, m_Data = "/etc/icinga2/conf.d/users.conf"}}
257
258
259 ## Core Dump <a id="development-debug-core-dump"></a>
260
261 When the Icinga 2 daemon crashes with a `SIGSEGV` signal
262 a core dump file should be written. This will help
263 developers to analyze and fix the problem.
264
265 ### Core Dump File Size Limit <a id="development-debug-core-dump-limit"></a>
266
267 This requires setting the core dump file size to `unlimited`.
268
269 Example for Systemd:
270
271     vim /usr/lib/systemd/system/icinga2.service
272
273     [Service]
274     ...
275     LimitCORE=infinity
276
277     systemctl daemon-reload
278
279     systemctl restart icinga2
280
281 Example for init script:
282
283     vim /etc/init.d/icinga2
284     ...
285     ulimit -c unlimited
286
287     service icinga2 restart
288
289 Verify that the Icinga 2 process core file size limit is set to `unlimited`.
290
291     cat /proc/`pidof icinga2`/limits
292     ...
293     Max core file size        unlimited            unlimited            bytes
294
295
296 ### Core Dump Kernel Format <a id="development-debug-core-dump-format"></a>
297
298 The Icinga 2 daemon runs with the SUID bit set. Therefore you need
299 to explicitly enable core dumps for SUID on Linux.
300
301     sysctl -w fs.suid_dumpable=1
302
303 Adjust the coredump kernel format and file location on Linux:
304
305     sysctl -w kernel.core_pattern=/var/lib/cores/core.%e.%p
306
307     install -m 1777 -d /var/lib/cores
308
309 MacOS:
310
311     sysctl -w kern.corefile=/cores/core.%P
312
313     chmod 777 /cores
314
315 ### Core Dump Analysis <a id="development-debug-core-dump-analysis"></a>
316
317 Once Icinga 2 crashes again a new coredump file will be written. Please
318 attach this file to your bug report in addition to the general details.
319
320 Simple test case for a `SIGSEGV` simulation with `sleep`:
321
322     ulimit -c unlimited
323     sleep 1800&
324     [1] <PID>
325     kill -SEGV <PID>
326     gdb `which sleep` /var/lib/cores/core.sleep.<PID>
327     (gdb) bt
328     rm /var/lib/cores/core.sleep.*
329
330 Analyzing Icinga 2:
331
332     gdb /usr/lib64/icinga2/sbin/icinga2 core.icinga2.<PID>
333     (gdb) bt
334