2. printk | 3. klogd i syslogd | 4. strace i ltrace | 5. gdb i UML | 6. kdb i kgdb | > |
Jądro Linuxa, tak jak wszystkie skomplikowane programy, mimo ciągłego rozwoju (a może również z jego powodu) nie jest doskonałe, dlatego zachodzi konieczność odpluskwiania (debugowania) - usuwania błędów w formalnie poprawnym kodzie (takim, który można skompilować). Jednocześnie każde kompilowanie jądra, dokonywane po wprowadzeniu poprawek może być (i zazwyczaj jest) bardzo czasochłonne, dlatego poprawki te muszą być wyjątkowo dobrze przemyślane, a występujące błędy dobrze zdiagnozowane i udokumentowane. O ile jednak zwykłe programy, działające w trybie użytkownika, debugować jest łatwo, to debugowanie jądra systemu operacyjnego nastręcza dużych trudności. Pomiędzy bowiem jądrem a sprzętem nie ma żadnej warstwy, żadnego środowiska pozwalającego kontrolować wykonywanie jądra. Zostało jednak opracowanych kilka technik, pozwalających ten problem obejść.
Do technik tych należą:
printk
Używając debugera trzeba mieć na uwadze fakt, że jest to jedynie narzędzie pomocnicze. Poprawiając jądro systemu operacyjnego (i każdy inny program) należy przede wszystkim uważnie czytać kod i w nim szukać źródła błędu. Debuger jedynie dostarcza informacji o skutkach, jakie pociąga za sobą dany błąd, co dla programisty jest jedynie dodatkową informacją ułatwiającą dotarcie do błędnego kodu i stwierdzenia, na czym polega problem.
Dobrze jest pamiętać słowa Linus Torvaldsa:
I'm afraid that I've seen too many people fix bugs by looking at debugger output, and that almost inevitably leads to fixing the symptoms rather than the underlying problems,
gdyż na listach dyskusyjnych poświęconych Linuxowi i rozwiązywaniu problemów w pracy z nim pojawiają się propozycje naprawy błędów utrzymane w konwencji dobrze ilustrowanej przez poniższy przykład:
> I got a error undefined reference to `__bb_init_func' when > compiling uml with kernel 2.6.17.6, gcc 4.1.1 and glibc-2.4 (...) Try removing from arch/um/kernel/gmon_syms.c these 2 lines: extern void __bb_init_func(void *); EXPORT_SYMBOL(__bb_init_func);
Nie trzeba tłumaczyć, że takie usunięcie dwóch linijek bez uprzedniego, dokładnego poznania ich fukcji i przyczyny ich obecności w tym miejscu kodu może prowadzić do zupełnie nieoczekiwanych efektów. Nawet, jeżeli kompilacja takiego kodu się powiedzie...
2. printk | 3. klogd i syslogd | 4. strace i ltrace | 5. gdb i UML | 6. kdb i kgdb | > |