Linux Kernel live debugging, jak to się robi i jakie narzędzia są używane?

Jakie są najczęstsze i dlaczego nie rzadkie metody i narzędzia używane do debugowania na żywo w jądrze Linuksa? Wiem, że Linus dla np. jest przeciwko tego rodzaju debugowania dla jądra Linuksa lub przynajmniej było i dlatego nic nie zostało zrobione w tym sensie w tamtych latach, ale szczerze mówiąc dużo czasu minęło od 2000 roku i jestem ciekaw, czy ta mentalność zmieniła się w odniesieniu do projektu Linux i jakie obecne metody są używane do debugowania na żywo na serwerze. Jądro Linuksa w tej chwili (lokalne czy zdalne)?

Mile widziane są odniesienia do solucji i samouczków na temat wspomnianych technik i narzędzi.

Author: Shinnok, 2011-02-09

11 answers

Inną opcją jest użycie kontrolera ICE/JTAG oraz GDB. To rozwiązanie "sprzętowe" jest szczególnie używane w systemach wbudowanych,

Ale na przykład Qemu oferuje podobne funkcje:

  • Uruchom qemu z "zdalnym" stubem gdb, który nasłuchuje na "localhost:1234' : qemu -s ...,

  • Następnie w GDB otwierasz plik jądra vmlinux skompilowany z informacjami o debugowaniu (możesz rzucić okiem na ten wątek listy dyskusyjnej gdzie omawiają unoptimization jądra).

  • Połącz GDB i Qemu: target remote localhost:1234

  • Zobacz swoje NA ŻYWO kernel:

    (gdb) where
    #0  cpu_v7_do_idle () at arch/arm/mm/proc-v7.S:77
    #1  0xc0029728 in arch_idle () atarm/mach-realview/include/mach/system.h:36
    #2  default_idle () at arm/kernel/process.c:166
    #3  0xc00298a8 in cpu_idle () at arch/arm/kernel/process.c:199
    #4  0xc00089c0 in start_kernel () at init/main.c:713
    

Niestety, debugowanie przestrzeni użytkownika nie jest możliwe do tej pory z GDB (brak informacji o liście zadań, brak przeprogramowania MMU, aby zobaczyć różne konteksty procesów, ...), ale jeśli pozostaniesz w przestrzeni jądra, jest to całkiem wygodne.

  • info threads poda ci listę i stany różnych Procesory

EDIT:

Więcej szczegółów na temat procedury można znaleźć w tym pliku PDF:

Debugowanie Systemów Linux przy użyciu GDB i QEMU .

 29
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-22 10:37:05

Podczas debugowania jądra Linuksa możemy użyć kilku narzędzi, na przykład debugerów (KDB, KGDB), dumping while crashed (LKCD), tracing toolkit (LTT, LTTV, LTTng), custom kernel instruments (dprobes, kprobes). W poniższej sekcji próbowałem podsumować większość z nich, mam nadzieję, że pomogą.

LKCD (Linux Kernel Crash Dump) narzędzie pozwala systemowi Linux na zapisanie zawartości jego pamięci w przypadku awarii. Dzienniki te mogą być dalej analizowane pod kątem przyczyny crash. Zasoby dotyczące LKCD

Oops gdy kernel wykryje problem, wyświetla komunikat Oops. Taki komunikat jest generowany przez polecenia printk w programie obsługi błędów (arch/*/kernel/traps.c). Dedykowany bufor pierścieniowy w jądro używane przez polecenia printk. Oops zawiera informacje takie jak procesor, na którym wystąpił UPS, zawartość rejestrów procesora, liczba UPS, opis, stos back trace i inne. Zasoby dotyczące jądra Oops

Dynamiczny Sondy jest jednym z popularnych narzędzi debugowania dla Linuksa, który został opracowany przez IBM. Narzędzie to umożliwia umieszczenie "sondy" w niemal każdym miejscu w systemie, zarówno w przestrzeni użytkownika, jak i jądra. Sonda składa się z jakiegoś kodu (napisanego w wyspecjalizowanym, zorientowanym na stosy języku), który jest wykonywany, gdy kontrola uderzy w dany punkt. Zasoby dotyczące sondy dynamicznej wymienione poniżej

Linux Trace Toolkit jest łatką do jądra i zestawem powiązanych narzędzi, które umożliwiają śledzenie zdarzeń w jądrze. Ślad zawiera informacje o czasie i może stworzyć w miarę kompletny obraz tego, co wydarzyło się w danym okresie czasu. Zasoby LTT, LTT Viewer i LTT Next Generation

MEMWATCH jest narzędziem do wykrywania błędów pamięci typu open source. Działa poprzez zdefiniowanie MEMWATCH w instrukcji gcc i dodanie pliku nagłówkowego do naszego kodu. Dzięki temu możemy śledzić pamięć przecieki i uszkodzenia pamięci. Zasoby dotyczące MEMWATCH

Ftrace jest dobrym frameworkiem śledzenia dla jądra Linuksa. ftrace śledzi wewnętrzne operacje jądra. To narzędzie zawarte w jądrze Linuksa w wersji 2.6.27. Dzięki różnym wtyczkom tracer, ftrace może być ukierunkowany na różne statyczne punkty tracepointy, takie jak zdarzenia planowania, przerwania, odwzorowane w pamięci wejścia / wyjścia, przejścia stanu mocy procesora i operacje związane z systemami plików i wirtualizacją. Ponadto dostępne jest dynamiczne śledzenie wywołań funkcji jądra, opcjonalnie ograniczone do podzbioru funkcji za pomocą Globów oraz z możliwością generowania wykresów wywołań i zapewnienia wykorzystania stosu. Dobry samouczek ftrace znajdziesz na https://events.linuxfoundation.org/slides/2010/linuxcon_japan/linuxcon_jp2010_rostedt.pdf

Ltrace jest narzędziem do debugowania w Linuksie, używanym do wyświetlania połączeń użytkownika aplikacja space sprawia, że biblioteki współdzielone. To narzędzie może być używane do śledzenia dowolnego dynamicznego wywołania funkcji biblioteki. Przechwytuje i rejestruje dynamiczne wywołania biblioteki, które są wywoływane przez wykonywany proces oraz sygnały, które są odbierane przez ten proces. Może również przechwytywać i drukować wywołania systemowe wykonywane przez program.

KDB jest debugerem jądra Linuksa. KDB podąża za uproszczonym interfejsem w stylu powłoki. Możemy go używać do sprawdzania pamięci, rejestrów, list procesów, dmesg, a nawet ustawiania punktów przerwania, aby zatrzymać się w określonym miejscu. Poprzez KDB możemy ustawić punkty przerwania i wykonać jakąś podstawową kontrolę nad uruchomieniem jądra (, chociaż KDB nie jest debuggerem na poziomie źródłowym ). Kilka przydatnych zasobów dotyczących KDB

KGDB jest przeznaczony do użycia jako debugger na poziomie źródłowym dla jądra Linuksa. Jest używany wraz z gdb do debugowania jądra Linuksa. Do korzystania z kgdb potrzebne są dwie maszyny. Jedna z tych maszyn jest maszyną rozwojową, a druga jest maszyną docelową. Jądro do debugowania działa na maszynie docelowej. Oczekuje się, że gdb może być użyte do "włamania się" do jądra w celu sprawdzenia pamięci, zmiennych i przejrzenia informacji o stosie wywołań, podobnie jak programista aplikacji używałby gdb do debugowania aplikacji. Możliwe jest umieszczanie punktów przerwania w kodzie jądra i wykonywanie pewnych ograniczonych kroków wykonawczych. Kilka przydatnych zasobów dotyczących KGDB

 23
Author: Md Mahbubur Rahman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-02 12:17:41

Według wiki, kgdb została połączona z jądrem w 2.6.26, czyli w ciągu ostatnich kilku lat. kgdbjest zdalnym debugerem , więc aktywujesz go w swoim jądrze , a następnie dołączasz do niego gdb. Mówię jakoś, ponieważ wydaje się, że jest wiele opcji-patrz Podłączanie gdb . Biorąc pod uwagę, że kgdb jest teraz w drzewie źródłowym, powiedziałbym, że w przyszłości tego chcesz używać.

Wygląda na to, że Linus się poddał. Chciałbym jednak podkreślić jego argumentacja - powinieneś wiedzieć, co robisz i dobrze znać system. To ziemia jądra. Jeśli coś pójdzie nie tak, nie dostajesz segfault, dostajesz coś od jakiegoś niejasnego problemu później, aż do upadku całego systemu. Oto smoki. Zachowaj ostrożność, zostałeś ostrzeżony.
 20
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-09 11:15:23

Kolejnym dobrym narzędziem do debugowania "na żywo" jest kprobes / dynamic probe.

Pozwala to dynamicznie budować małe moduły, które działają po wykonaniu określonych adresów - coś w rodzaju punktu przerwania.

Dużą ich zaletą są:

  1. nie wpływają one na system - tzn. gdy zostanie uderzona lokacja-po prostu wykona kod - nie zatrzyma całego jądra.
  2. nie potrzebujesz dwóch różnych systemów połączonych ze sobą (target i debug) jak z kgdb

Najlepiej jest wykonywać takie czynności, jak uderzanie punktu przerwania, sprawdzanie, jakie są wartości danych, sprawdzanie, czy coś zostało zmienione/nadpisane itp. Jeśli chcesz "przejść przez KOD" - nie robi tego.

Dodatek - 2018:

Kolejną bardzo wydajną metodą jest program po prostu nazywany "perf", który zwija wiele narzędzi (jak sondy dynamiczne) i zastępuje/deprymuje inne (jak oprofile).

W szczególności polecenie perf probe może być użyte do z łatwością twórz / dodawaj dynamiczne sondy do systemu, po czym perf record może pobierać próbki systemu i raportować informacje (i wstecz), gdy sonda zostanie trafiona w celu raportowania przez perf report (lub perf script). Jeśli masz dobre symbole debugowania w jądrze, możesz wyciągnąć świetne dane z systemu bez zdejmowania jądra. Wykonaj man perf (w Google lub w systemie) aby uzyskać więcej informacji na temat tego narzędzia lub zobacz tę wspaniałą stronę na nim:

Http://www.brendangregg.com/perf.html

 15
Author: Brad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-01 13:45:26

KGDB + QEMU krok po kroku

KGDB jest podsystemem jądra, który pozwala na krok debugowania samego jądra z hosta GDB.

Mój przykład QEMU + Buildroot jest dobrym sposobem, aby spróbować go bez prawdziwego sprzętu: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/1969cd6f8d30dace81d9848c6bacbb8bad9dacd8#kgdb

Plusy i minusy a inne metody:

  • advantage vs QEMU:
    • często nie masz oprogramowania emulacja dla Twojego urządzenia, ponieważ dostawcy sprzętu nie lubią wypuszczać dokładnych modeli oprogramowania dla swoich urządzeń]}
    • prawdziwy sprzęt o wiele szybszy niż QEMU
  • Nie ma potrzeby używania dodatkowego sprzętu JTAG, łatwiejsza konfiguracja]}
  • wady vs QEMU i JTAG: mniejsza widoczność i bardziej natrętna. KGDB polega na tym, że niektóre części jądra pracują, aby móc komunikować się z hostem. Więc np. psuje się w panice, nie można obejrzeć Boota Sekwencja.

Główne kroki to:

  1. Skompiluj jądro z:

    CONFIG_DEBUG_KERNEL=y
    CONFIG_DEBUG_INFO=y
    
    CONFIG_CONSOLE_POLL=y
    CONFIG_KDB_CONTINUE_CATASTROPHIC=0
    CONFIG_KDB_DEFAULT_ENABLE=0x1
    CONFIG_KDB_KEYBOARD=y
    CONFIG_KGDB=y
    CONFIG_KGDB_KDB=y
    CONFIG_KGDB_LOW_LEVEL_TRAP=y
    CONFIG_KGDB_SERIAL_CONSOLE=y
    CONFIG_KGDB_TESTS=y
    CONFIG_KGDB_TESTS_ON_BOOT=n
    CONFIG_MAGIC_SYSRQ=y
    CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
    CONFIG_SERIAL_KGDB_NMI=n
    
    Większość z nich nie jest obowiązkowa, ale to właśnie przetestowałem.
  2. Dodaj do komendy QEMU:

    -append 'kgdbwait kgdboc=ttyS0,115200' \
    -serial tcp::1234,server,nowait
    
  3. Uruchom GDB z katalogu głównego drzewa źródłowego jądra Linuksa z:

    gdb -ex 'file vmlinux' -ex 'target remote localhost:1234'
    
  4. W GDB:

    (gdb) c
    

    I but powinien się skończyć.

  5. W QEMU:

    echo g > /proc/sysrq-trigger
    

    I GDB powinny przerwa.

  6. Teraz skończyliśmy, możesz używać GDB jak zwykle:

    b sys_write
    c
    

Testowane w Ubuntu 14.04.

KGDB + Raspberry Pi

Dokładnie taka sama konfiguracja jak powyżej prawie działała na Raspberry Pi 2, Raspbian Jessie 2016-05-27.

Musisz tylko nauczyć się wykonywać kroki QEMU na Pi, które są łatwe Googlable:

  • Dodaj opcje konfiguracyjne i przekompiluj jądro tak, jak wyjaśniono na https://www.raspberrypi.org/documentation/linux/kernel/building.md w domyślnej kompilacji jądra niestety brakowało opcji, w szczególności nie było symboli debugowania, więc potrzebna jest rekompilacja.

  • Edytuj cmdline.txt partycji rozruchowej i dodaj:

    kgdbwait kgdboc=ttyAMA0,115200
    
  • Połącz {[11] } z serią za pomocą:

    arm-linux-gnueabihf-gdb -ex 'file vmlinux' -ex 'target remote /dev/ttyUSB0'
    

    Jeśli nie jesteś zaznajomiony z serią, sprawdź to: https://www.youtube.com/watch?v=da5Q7xL_OTo Wszystko czego potrzebujesz to tanie adapter jak ten . Upewnij się, że możesz uzyskać powłokę przez serial, aby upewnić się, że działa przed wypróbowaniem KGDB.

  • Do:

    echo g | sudo tee /proc/sysrq-trigger
    

    Z wnętrza sesji SSH, ponieważ serial jest już zajęty przez GDB.

Dzięki tej konfiguracji mogłem umieścić breakpoint w sys_write, wstrzymać wykonywanie programu, wyświetlić źródło listy i kontynuować.

Jednak czasami, gdy zrobiłem next W sys_write GDB po prostu wisiał i drukował ten Komunikat o błędzie kilka razy:

Ignoring packet error, continuing...

Więc nie jestem pewien, czy coś jest nie tak z moją konfiguracją, lub jeśli oczekuje się tego z powodu tego, co jakiś proces tła robi w bardziej złożonym obrazie Raspbian.

Powiedziano mi również, aby spróbować i wyłączyć wieloprocesorowe z opcjami rozruchu Linuksa, ale nie próbowałem jeszcze.

 7
Author: Ciro Santilli TRUMP BAN IS BAD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-25 21:10:14

Właściwie żartem jest to, że Linux ma debugger w jądrze od 2.2.12, xmon, ale tylko dla architektury powerpc (w rzeczywistości był to ppc wtedy).

Nie jest to debugger na poziomie źródłowym i jest prawie całkowicie nieudokumentowany, ale nadal.

Http://lxr.linux.no/linux-old+v2. 2.12/arch/ppc/xmon / xmon. c#l119

 4
Author: mpe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-10 12:44:55

QEMU + GDB procedura krok po kroku testowana na Ubuntu 16.10 host

Aby szybko zacząć od zera, zrobiłem minimalny w pełni zautomatyzowany przykład QEMU + Buildroot pod adresem: https://github.com/cirosantilli/linux-kernel-module-cheat główne kroki zostały omówione poniżej.

Najpierw uzyskaj główny system plików rootfs.cpio.gz. Jeśli potrzebujesz, rozważ:

Następnie na jądrze Linuksa:

git checkout v4.9
make mrproper
make x86_64_defconfig
cat <<EOF >.config-fragment
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_KERNEL=y
CONFIG_GDB_SCRIPTS=y
EOF
./scripts/kconfig/merge_config.sh .config .config-fragment
make -j"$(nproc)"
qemu-system-x86_64 -kernel arch/x86/boot/bzImage \
                   -initrd rootfs.cpio.gz -S -s

Na innym terminalu, Załóżmy, że chcesz rozpocząć debugowanie od start_kernel:

gdb \
    -ex "add-auto-load-safe-path $(pwd)" \
    -ex "file vmlinux" \
    -ex 'set arch i386:x86-64:intel' \
    -ex 'target remote localhost:1234' \
    -ex 'break start_kernel' \
    -ex 'continue' \
    -ex 'disconnect' \
    -ex 'set arch i386:x86-64' \
    -ex 'target remote localhost:1234'

I skończyliśmy!!

Dla jądra Moduły zobacz: jak debugować moduły jądra Linuksa za pomocą QEMU?

Dla Ubuntu 14.04, GDB 7.7.1, hbreak było potrzebne, break punkty przerwania oprogramowania były ignorowane. Już nie w 16.10. Zobacz też: https://bugs.launchpad.net/ubuntu / + source / qemu-kvm/ + bug/901944

Bałagan disconnect i co po nim jest, aby obejść błąd:

Remote 'g' packet reply is too long: 000000000000000017d11000008ef4810120008000000000fdfb8b07000000000d352828000000004040010000000000903fe081ffffffff883fe081ffffffff00000000000e0000ffffffffffe0ffffffffffff07ffffffffffffffff9fffff17d11000008ef4810000000000800000fffffffff8ffffffffff0000ffffffff2ddbf481ffffffff4600000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000

Powiązane wątki:

Zobacz też:

Znane ograniczenia:

 4
Author: Ciro Santilli TRUMP BAN IS BAD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-27 07:58:16

Jako ktoś, kto dużo pisze kod jądra muszę powiedzieć, że nigdy nie używałem kgdb, a rzadko używałem kprobów itp.

Jest to nadal często najlepszym podejściem do wrzucenia jakiegoś strategicznego printks. W nowszych jądrach {[1] } jest to dobry sposób, aby to zrobić bez spamowania dmesg.

 3
Author: mpe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-10 12:52:16

User mode Linux (UML)

Https://en.wikipedia.org/wiki/User-mode_Linux

Kolejna wirtualizacja inna metoda, która umożliwia debugowanie kodu jądra.

UML jest bardzo pomysłowy: jest zaimplementowany jako ARCH, podobnie jak x86, ale zamiast używać instrukcji niskiego poziomu, implementuje funkcje ARCH za pomocą wywołań systemowych userland.

Rezultatem jest to, że jesteś w stanie uruchomić kod jądra Linuksa jako proces userland na Linuksie gospodarzu!

Najpierw zrób rootfs i uruchom go jak pokazano na: https://unix.stackexchange.com/questions/73203/how-to-create-rootfs-for-user-mode-linux-on-fedora-18/372207#372207

um defconfig ustawia CONFIG_DEBUG_INFO=y domyślnie (tak, jest to rzecz rozwojowa), więc jesteśmy w porządku.

On gość:

i=0
while true; do echo $i; i=$(($i+1)); done

Na serwerze w innej powłoce:

ps aux | grep ./linux
gdb -pid "$pid"

W GDB:

break sys_write
continue
continue

A teraz kontrolujesz licznik z GDB i widzisz źródło jako oczekiwane.

Plusy:

  • w pełni zawarty w drzewie linii głównej jądra Linuksa
  • Bardziej lekki niż pełna emulacja systemu QEMU]}

Wady:

Zobacz ponadto: https://unix.stackexchange.com/questions/127829/why-would-someone-want-to-run-usermode-linux-uml

 3
Author: Ciro Santilli TRUMP BAN IS BAD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-21 07:44:53

Jesteście w błędzie, kgdb nadal działa dobrze dla najnowszego jądra, musisz zająć się konfiguracją jądra podzielonego obrazu, optymalizacją randomizacji.

Kgdb przez port szeregowy jest bezużyteczny, ponieważ żaden komputer obecnie nie obsługuje DB9 na porcie szeregowym płyty głównej, port szeregowy USB nie obsługuje trybu polling.

Nowa gra to kgdboe, poniżej znajduje się log trace:

Poniżej znajduje się maszyna hosta, vmlinux pochodzi z maszyny docelowej

root@Thinkpad-T510:~/KGDBOE# gdb vmlinux
Reading symbols from vmlinux...done.
(gdb) target remote udp:192.168.1.22:31337
1077    kernel/debug/debug_core.c: No such file or directory.
(gdb) l oom_kill_process 
828 mm/oom_kill.c: No such file or directory.
(gdb) l oom_kill_process 
828 in mm/oom_kill.c
(gdb) break oom_kill_process
Breakpoint 1 at 0xffffffff8119e0c0: file mm/oom_kill.c, line 833.
(gdb) c
Continuing.
[New Thread 1779]
[New Thread 1782]
[New Thread 1777]
[New Thread 1778]
[New Thread 1780]
[New Thread 1781]
[Switching to Thread 1779]

Thread 388 hit Breakpoint 1, oom_kill_process (oc=0xffffc90000d93ce8, message=0xffffffff82098fbc "Out of memory")
at mm/oom_kill.c:833
833 in mm/oom_kill.c
(gdb) s
834 in mm/oom_kill.c
(gdb) 

On peer target maszyna, poniżej znajduje się sposób na awarię i przechwycenie jej przez maszynę hosta

#swapoff -a
#stress -m 4 --vm-bytes=500m
 1
Author: unhmble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-22 05:01:53

Kgdb i gdb są prawie bezużyteczne do debugowania jądra, ponieważ kod jest tak zoptymalizowany, że nie ma żadnego związku ze źródłem orioginalnym i wiele varuiables jest zoptymalizowanych. To sprawia, że steppijng, a więc przejście przez źródło jest niemożliwe, badanie zmiennych jest niemożliwe i dlatego jest najbardziej punktowe.

Faktycznie jest gorzej niż bezużyteczny, to faktycznie daje fałszywą infoprmację tak odłączony jest kod, który ollooking do rzeczywistego kodu uruchomieniowego.

I Nie, Nie można wyłączyć optymalizacji w jądrze, nie kompiluje się.

Muszę powiedzieć, że wychodząc ze środowiska jądra windows, Brak porządnego debuggera jest bez sensu, biorąc pod uwagę, że istnieje śmieciowy kod do utrzymania.

 -4
Author: matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 14:25:11