Debugger — dastur bajarilishini nazorat qilish, to‘xtatish va ichki holatini ko‘rish orqali xatolarni aniqlashga yordam beradigan vosita.
Debugger source code, machine instruction, variable, register, memory, thread va stack frame’larni tahlil qiladi.
U dasturga process sifatida ulanadi yoki dasturni o‘zi ishga tushiradi.
Debug symbol
Compiled binary machine code’dan iborat. Source nomlari va qatorlar avtomatik saqlanmasligi mumkin.
Compiler debug information qo‘shadi:
Debug symbol binary ichida yoki alohida faylda saqlanadi.
Breakpoint
Breakpoint dastur ma’lum joyga yetganda bajarilishni to‘xtatadi.
Turlari:
- source line breakpoint;
- function breakpoint;
- address breakpoint;
- conditional breakpoint;
- exception breakpoint;
- data breakpoint.
To‘xtagach developer holatni tekshiradi.
Software breakpoint
Debugger instruction byte’ini maxsus trap instruction bilan vaqtincha almashtiradi.
CPU trapga yetganda debugger nazorat oladi.
Keyin original instruction tiklanib, single-step bajarilishi mumkin.
Read-only code va self-modifying code holatida alohida boshqaruv kerak.
Hardware breakpoint
CPU debug registerlari ma’lum address bajarilishi yoki data access’ini kuzatadi.
Afzalligi:
- code’ni o‘zgartirmaydi;
- read/write watchpoint;
- ROM yoki protected code’da ishlashi mumkin.
Kamchiligi — hardware slotlar soni cheklangan.
Conditional breakpoint
Faqat shart rost bo‘lganda to‘xtaydi.
Misol:
user_id == 5000
Loopning minglab iterationi orasida kerakli holatni topishga yordam beradi.
Shartni har safar baholash programni sekinlashtirishi mumkin.
Watchpoint
Variable yoki memory manzil o‘zgarganda debugger to‘xtaydi.
Bu noto‘g‘ri yozuv manbasini topishda foydali.
Object ko‘chishi, garbage collection va stack variable umriga qarab watchpoint murakkab bo‘lishi mumkin.
Step amallari
Step into
Keyingi source qatorni bajaradi va function call ichiga kiradi.
Step over
Function callni bajaradi, lekin ichiga kirmaydi.
Step out
Joriy function tugaguncha davom etadi va callerga qaytadi.
Continue
Keyingi breakpoint yoki signalgacha ishlaydi.
Call stack
Debugger threadning function call zanjirini ko‘rsatadi.
main
→ handle_request
→ parse_payload
→ decode_field
Har frame uchun:
ko‘riladi.
Optimization stackni o‘zgartirishi mumkin.
Variable inspection
Debugger local, global va object fieldlarni ko‘rsatadi.
U expression baholashi mumkin:
items.length
user.permissions
buffer[0:16]
Expression side effect qilsa program holatini o‘zgartirishi mumkin.
Register
Low-level debuggingda:
ko‘riladi.
Calling convention argumentlar qaysi registerda ekanini tushunishga yordam beradi.
Memory view
Debugger memory’ni:
- byte;
- integer;
- pointer;
- string;
- structure;
- disassembly
ko‘rinishida chiqaradi.
Endianness va alignment hisobga olinadi.
Disassembly
Source mavjud bo‘lmasa yoki optimized code tahlil qilinsa machine instructionlar ko‘riladi.
Debugger current instruction va branch targetni ko‘rsatadi.
Source va assembly mixed view compiler qanday code yaratganini tushuntiradi.
Processga ulanish
Debugger ishlayotgan processga attach qilishi mumkin.
Operatsion tizim permission va tracing policy tekshiradi.
Production processni debugger bilan to‘xtatish xizmat uzilishiga sabab bo‘lishi mumkin.
Remote debugging
Target qurilmada kichik debug server, developer mashinasida to‘liq debugger ishlaydi.
Embedded, container, virtual machine va remote serverlarda ishlatiladi.
Protocol orqali:
- register;
- memory;
- breakpoint;
- continue
boshqariladi.
Core dump
Crash vaqtida process xotira holati core dumpga yozilishi mumkin.
Debugger executable va symbol bilan core’ni ochadi.
Ko‘riladigan ma’lumot:
Core dump ichida maxfiy data bo‘lishi mumkin.
Exception debugging
Managed runtime debugger exception:
- thrown paytda;
- caught bo‘lmaganda;
- ma’lum turda
to‘xtashi mumkin.
Exception keyin catch qilinsa ham asl manbani topish uchun first-chance break foydali.
Multi-thread debugging
Bir thread breakpointga yetganda debugger:
- barcha threadni;
- faqat shu threadni
to‘xtatishi mumkin.
bilan ko‘riladi.
Deadlock tahlilida barcha thread stacklari kerak.
Race condition
Debugger program timingini o‘zgartiradi. Race condition debugger ostida yo‘qolishi mumkin.
Bu Heisenbug deb ataladi.
Thread sanitizer, tracing va deterministic replay qo‘shimcha vosita hisoblanadi.
Reverse debugging
Ba’zi debugger execution tarixini yozib, oldingi holatga qaytishga imkon beradi.
Bu:
- noto‘g‘ri qiymat qayerda paydo bo‘ldi;
- crashdan oldingi qadam;
- race
ni tahlil qilishda foydali.
Recording katta storage va performance xarajati talab qiladi.
Source mapping
Transpiled yoki minified code original source’ga source map orqali bog‘lanadi.
Browser debugger TypeScript yoki original JavaScript qatorini ko‘rsatishi mumkin.
Source map productionga ochiq tarqatilsa source code haqida ma’lumot oshkor bo‘lishi mumkin.
Optimized code
Optimization sabab:
- variable optimized out;
- function inline;
- qator tartibi o‘zgargan;
- loop vectorized;
- tail call;
- register reuse
bo‘lishi mumkin.
Debug build xatoni oson ko‘rsatadi, ammo release-only muammo uchun optimized binary va mos symbol kerak.
Logging bilan farqi
Debugger interactive ichki holatni ko‘radi, lekin programni to‘xtatishi mumkin.
Logging productionda tarix beradi, ammo oldindan yozilgan ma’lumot bilan cheklangan.
Ikkalasi tracing, metrics va profiling bilan birga ishlatiladi.
Xavfsizlik
Debugger process memory va secretlarni ko‘ra oladi.
Productionda:
- attach permission;
- ptrace policy;
- admin access;
- core dump retention;
- symbol server;
- remote debug port
cheklanadi.
Debug endpointni internetga ochish code execution xavfi tug‘dirishi mumkin.
Diagnostika jarayoni
Debugger bilan:
- xato qayta hosil qilinadi;
- minimal breakpoint tanlanadi;
- input va state tekshiriladi;
- noto‘g‘ri qiymatning birinchi nuqtasi topiladi;
- sabab tuzatiladi;
- regression test yoziladi.
Faqat crash qatorini emas, u yerga noto‘g‘ri state qanday kelganini topish muhim.
Bog‘liq tushunchalar
Breakpoint, Watchpoint, Stack trace, Core dump, Debug symbol, Disassembly, Register, Exception, Remote debugging, Heisenbug