Call stack — faol funksiya chaqiriqlarining qaytish nuqtasi, argument, lokal o‘zgaruvchi va saqlangan registrlarini LIFO tartibida saqlaydigan xotira tuzilmasidir. Har thread odatda o‘z stackiga ega. Funksiya chaqirilganda stack frame yaratiladi, qaytganda u olib tashlanib boshqaruv callerga qaytadi.
Stack frame
Frame tarkibi ABI, compiler optimizatsiyasi va arxitekturaga bog‘liq. Unda return address, oldingi frame pointer, callee-saved registrlar, stackga sig‘dirilgan argumentlar va lokal qiymatlar bo‘lishi mumkin. Ko‘p argument registrda uzatiladi, faqat ortiqchasi stackga tushadi. Compiler ayrim lokalni faqat registrda saqlaydi.
Prologue stack pointer’ni siljitib frame uchun joy ajratadi, epilogue holatni tiklaydi. Frame pointer optimizatsiyada olib tashlanishi mumkin. Debugger unwind metadata yoki stack pointer va return addresslardan chaqiriq zanjirini tiklaydi.
O‘sish va chegaralar
Ko‘p arxitekturada stack yuqori manzildan pastga o‘sadi, ammo bu universal qoida emas. Operatsion tizim virtual address oralig‘i va guard page ajratadi. Stack pointer guarddan o‘tsa page fault stack overflow sifatida jarayonni to‘xtatishi mumkin. Thread soni ko‘p bo‘lsa har biri uchun katta rezerv virtual manzil sarflaydi.
Lokal katta massiv stackni tez to‘ldiradi. Katta yoki o‘zgaruvchan hajmli buffer heapda yoki caller boshqaradigan storage’da saqlanadi. Recursion har darajada frame qo‘shadi; base case bo‘lmasa limitga yetadi. Tail call optimization ayrim rekursiyani frame qo‘shmasdan bajarishi mumkin, lekin til va compiler kafolatiga bog‘liq.
Exception va unwinding
Exception yuqoriga tarqalganda runtime frame’larni unwind qiladi va scope cleanup yoki destructorlarni chaqiradi. Unwind metadata return address va saqlangan registrlarni topishga yordam beradi. Native til chegarasida noto‘g‘ri exception ABI yoki buzilgan stack cleanup ishlamasligiga olib kelishi mumkin.
Signal yoki interrupt alohida stackdan foydalanishi mumkin. Kernel stack user stackdan ajratiladi. Juda chuqur kernel call chain xavfli, chunki kernel stack ko‘pincha qat’iy kichik hajmga ega.
Xavfsizlik va diagnostika
Stack buffer overflow return address yoki control data’ni buzishi mumkin. Stack canary, ASLR, non-executable stack va control-flow protection ekspluatatsiyani qiyinlashtiradi. Memory-safe til indexni tekshiradi, ammo native extensionda xato qolishi mumkin.
Stack trace crash paytidagi chaqiriq zanjirini ko‘rsatadi. Optimized buildda inlining, tail call va symbol yo‘qligi trace’ni o‘zgartiradi. Build IDga mos debug symbol saqlanmasa manzillarni funksiya va qatorga aylantirish qiyin. Stack sample profiler dastur vaqtini qaysi call path sarflayotganini statistik aniqlaydi, lekin juda qisqa funksiyalar sample orasida ko‘rinmasligi mumkin.
Asinxron stack
Async funksiya kutish nuqtasida native stack frame’ni bo‘shatib, davom holatini heapdagi state machine’da saqlashi mumkin. Keyin boshqa thread’da davom etganda oddiy native stack faqat scheduler va continuationni ko‘rsatadi. Runtime logical async stackni task parent va await bog‘lanishidan tiklaydi. Context propagation yo‘qolsa trace bir so‘rovning bo‘laklarini bog‘lay olmaydi. Coroutine stackful bo‘lsa alohida kichik stack yoki segmentli stack ishlatishi mumkin. Debugger va profiler runtime modelini bilishi kerak; faqat OS thread stackiga qarash asinxron call chainning asl tashabbuskorini ko‘rsatmasligi mumkin.
Nosozlik paytidagi stack trace chaqiruv stekining suratini beradi. Undagi freymlar funksiyalar qanday ketma-ketlikda chaqirilganini ko‘rsatadi, biroq optimallashtirilgan kodda ayrim chaqiruvlar birlashtirilishi yoki butunlay ko‘rinmasligi mumkin.
Bog‘liq tushunchalar
Stack frame, Stack pointer, ABI, Recursion, Stack overflow, Stack unwinding