---
title: 'Hata Ayıklayıcı Kullanımı'
source: 'https://academia.sh/tr/kurslar/c-sistem-programlama/hata-ayiklayici-kullanimi'
course: 'C ile Sistem Programlama'
language: tr
updated: '2026-09-26T03:02:44+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Kesme noktası tabanlı gözlemin adımlar arasındaki bir değeri neden atladığını ölçer'
    - 'Gözetleme noktasının her yazmada durarak aynı değeri neden gördüğünü gösterir'
    - 'Çekirdek dökümünün ne için kullanıldığını, koşturmadan ölçüm çerçevesine yerleştirir'
---

# Hata Ayıklayıcı Kullanımı

Bir kesme noktasının adımlar arasındaki ara değeri neden hiç görmediğini, gözetleme noktasının aynı değeri neden gördüğünü C içinde modelleyerek ölçer.

Bir test kaldığında hangi girdinin hangi adımda beklenenden saptığı bilinmez — yalnız
sonuç bilinir. Bir hata ayıklayıcı, çalışan bir programın ara değerlerini durdurarak ya
da izleyerek görünür kılar. Ama "görünür kılmak" tek bir anlam taşımıyor: bir hata
ayıklayıcının **neyi** gördüğü, ona nasıl durması söylendiğine bağlı.

Bir önceki ders, bir testin başarısız olduğunu gösteriyordu ama neden başarısız olduğunu
göstermiyordu. Onaylama kalırsa bilinen tek şey, koşulun yanlış olduğu; koşula giden
değerin hangi adımda o hale geldiği testin kendi çıktısında görünmez. Bir hata ayıklayıcı
bu boşluğu, programı istenen bir noktada durdurarak ya da bir değişkenin her değişimini
izleyerek doldurur. İki yaklaşım da aynı çalışan süreci gözlemliyor olsa bile, hangi
adımların görüldüğü stratejiye göre değişir — ve bu fark, bir hatayı ararken hangi
değerin görülüp hangisinin kaçırıldığını doğrudan belirler.

Bu ders üç durma stratejisini karşılaştırıyor: konuma göre duran (kesme noktası), her
değişimde duran (gözetleme noktası) ve bir duruma göre duran (koşullu kesme noktası).
Üçü de aynı çalışan süreci gözlemliyor, ama her biri farklı bir soruya cevap vermek için
kuruldu — "şu adıma gelince ne oluyor", "bu değer ne zaman değişiyor" ve "bu durum ne
zaman gerçekleşiyor". Bir dördüncü araç, çekirdek dökümü, bambaşka bir zamanda devreye
girer: süreç artık çalışmıyorken, geride bıraktığı durumu okur. Dört aracın ortak paydası,
hepsinin aynı temel soruyu — programın bir andaki iç durumu neydi — farklı koşullar altında
yanıtlamasıdır.

## Kesme Noktası ve Gözetleme Noktası

Aşağıdaki model bir değişkene sırayla üç adımda üç değer yazan bir işlevi tanımlıyor.
Bu işlev iki farklı gözlem biçimiyle çalıştırılabiliyor: biri yalnız seçilmiş adımlarda
durup gözlemciyi çağırıyor, diğeri her adımda duruyor.

```c
// adim.h — uc adimlik yazma dizisi ve iki gozlem bicimi
#ifndef ADIM_H
#define ADIM_H

typedef void (*GozlemIslevi)(int adim, int deger);

/* Uc adimda bir degiskene sirayla 1, 2, 3 yazar. kesme_noktalari dizisinde
   olmayan bir adimda gozlemci hic cagrilmaz -- program o adimda durmadan
   ilerler. */
void kesme_noktasiyla_calistir(GozlemIslevi gozle, const int *kesme_noktalari, int sayisi);

/* Ayni uc adimlik yazma dizisi, ama gozlemci HER adimda cagrilir -- kesme
   noktasi listesi yok, cunku her yazma bir durma nedenidir. */
void gozetleme_noktasiyla_calistir(GozlemIslevi gozle);

/* Adim listesi yerine deger uzerinde bir kosul tanimlanir: gozlemci yalnizca
   deger esik'e ulastiginda cagrilir. Hangi adimda durulacagi onceden bilinmez,
   yalnizca hangi kosulda durulacagi bilinir. */
void kosullu_kesme_noktasiyla_calistir(GozlemIslevi gozle, int esik);

#endif
```

```c
// adim.c — kesme noktasi secici durur, gozetleme noktasi her yazmada durur
#include "adim.h"

static int kesme_noktasinda_mi(int adim, const int *noktalar, int sayisi) {
    for (int i = 0; i < sayisi; i++) {
        if (noktalar[i] == adim) return 1;
    }
    return 0;
}

void kesme_noktasiyla_calistir(GozlemIslevi gozle, const int *kesme_noktalari, int sayisi) {
    for (int adim = 0; adim < 3; adim++) {
        int deger = adim + 1;   /* adim 0 -> 1, adim 1 -> 2, adim 2 -> 3 */
        if (kesme_noktasinda_mi(adim, kesme_noktalari, sayisi)) {
            gozle(adim, deger);
        }
    }
}

void gozetleme_noktasiyla_calistir(GozlemIslevi gozle) {
    for (int adim = 0; adim < 3; adim++) {
        int deger = adim + 1;
        gozle(adim, deger);   /* her yazmada duruyor, secim yok */
    }
}

void kosullu_kesme_noktasiyla_calistir(GozlemIslevi gozle, int esik) {
    for (int adim = 0; adim < 3; adim++) {
        int deger = adim + 1;
        if (deger >= esik) {   /* adim numarasina degil, degerin kendisine bakiyor */
            gozle(adim, deger);
        }
    }
}
```

**PA8.** Adımlama burada tek bir döngünün ilerleyişi olarak modelleniyor: her döngü
turu bir adımı, gözlemcinin çağrılıp çağrılmaması ise o adımda durulup durulmadığını
temsil ediyor. Gerçek bir hata ayıklayıcı adım adım ilerlemeyi kullanıcının komutuyla
tetikler; burada zamanlamayı görünür kılmak için tek bir çalışma akışında yürütülüyor.

**PA9.** Koşul burada tek bir tamsayı karşılaştırmasına (`deger >= esik`) indirgeniyor;
gerçek bir hata ayıklayıcıda koşul rastgele bir boole ifadesi olabilir, ama mekanizma
aynıdır — her adımda koşul değerlendirilir, yalnız sağlandığında durulur.

Kesme noktası ile koşullu kesme noktası arasındaki fark, **neyin önceden bilindiğidir**.
Sıradan bir kesme noktası belirli adım numaralarında durur — hangi adımların ilginç
olduğu önceden bilinmelidir. Koşullu bir kesme noktası ise adım numarasına hiç bakmaz;
yalnız değerin kendisine bakar ve koşul her sağlandığında durur, kaçıncı adımda
olduğuna bakılmaksızın. Bu, "üçüncü adımda dur" ile "değer 2'ye ulaştığında dur"
arasındaki farktır — birincisi konuma, ikincisi duruma bakar. Konum önceden
bilinmediğinde ama durumun ne olması gerektiği biliniyorsa (örneğin bir sayacın belirli
bir eşiği geçtiği an), koşullu kesme noktası sıradan bir kesme noktasının yapamayacağı
bir şeyi yapar: adım sayısı yüzlerce ya da binlerce olsa bile, aranan durum yalnız bir
kez gerçekleştiğinde durur.

```c
// olcum.c — kesme noktasi 2'yi atliyor, gozetleme noktasi 2'yi goruyor
#include <stdio.h>
#include "adim.h"

static int gorulen_sayisi = 0;
static int gorulen_degerler[3];

static void kaydet(int adim, int deger) {
    (void)adim;
    gorulen_degerler[gorulen_sayisi] = deger;
    gorulen_sayisi++;
}

int main(void) {
    int noktalar[2] = { 0, 2 };   /* kesme noktalari 0. ve 2. adimda */

    kesme_noktasiyla_calistir(kaydet, noktalar, 2);
    printf("kesme noktasiyla gorulen sayisi: %d\n", gorulen_sayisi);
    printf("kesme noktasiyla ilk gorulen: %d\n", gorulen_degerler[0]);
    printf("kesme noktasiyla ikinci gorulen: %d\n", gorulen_degerler[1]);

    gorulen_sayisi = 0;
    gozetleme_noktasiyla_calistir(kaydet);
    printf("gozetleme noktasiyla gorulen sayisi: %d\n", gorulen_sayisi);
    printf("gozetleme noktasiyla ikinci gorulen: %d\n", gorulen_degerler[1]);

    gorulen_sayisi = 0;
    kosullu_kesme_noktasiyla_calistir(kaydet, 2);   /* deger 2'ye ulasinca dur */
    printf("kosullu kesme noktasiyla gorulen sayisi: %d\n", gorulen_sayisi);
    printf("kosullu kesme noktasiyla ilk gorulen: %d\n", gorulen_degerler[0]);
    printf("kosullu kesme noktasiyla ikinci gorulen: %d\n", gorulen_degerler[1]);
    return 0;
}
```

```text
kesme noktasiyla gorulen sayisi: 2
kesme noktasiyla ilk gorulen: 1
kesme noktasiyla ikinci gorulen: 3
gozetleme noktasiyla gorulen sayisi: 3
gozetleme noktasiyla ikinci gorulen: 2
kosullu kesme noktasiyla gorulen sayisi: 2
kosullu kesme noktasiyla ilk gorulen: 2
kosullu kesme noktasiyla ikinci gorulen: 3
```

Kesme noktaları 0. ve 2. adımda kuruldu; program bu iki adımda durdu ve sırasıyla 1 ile
3 değerlerini gördü. Aradaki 1. adımda değişken 2 değerini taşıdı, ama orada kesme
noktası olmadığı için gözlemci hiç çağrılmadı — 2 değeri hiç görülmedi. Aynı üç adımlık
dizi gözetleme noktasıyla çalıştırıldığında gözlemci her adımda çağrıldı: üç değer de
kaydedildi ve ikinci gözlem tam olarak kesme noktasının kaçırdığı 2 değeriydi.

Son üç satır koşullu kesme noktasının davranışını gösteriyor. Eşik 2 olarak verildiğinde,
0. adımdaki değer (1) eşiğin altında kaldığı için gözlemci orada hiç çağrılmadı; 1. ve 2.
adımlardaki değerler (2 ve 3) eşiğe ulaştığı ya da geçtiği için ikisinde de durdu. Görülen
sayı 2, ilk görülen 2, ikinci görülen 3 — sıradan kesme noktasının 0. ve 2. adımda durup
1 ile 3'ü görmesinden farklı bir küme. İki mekanizma da aynı üç adımlık diziyi tarıyor,
ama biri **konuma** göre seçim yapıyor, diğeri **duruma** göre; bu yüzden aynı diziden
farklı gözlem kümeleri çıkarıyorlar. Bu fark, hangi mekanizmanın seçileceğini önceden
bilinen bilginin türü belirliyor: aranan adım biliniyorsa kesme noktası yeterli ve daha
ucuzdur, aranan yalnız bir durum (bir değerin belirli bir eşiği geçmesi gibi) ise ve
hangi adımda gerçekleşeceği bilinmiyorsa koşullu kesme noktası gerekir.

Gözetleme noktasıyla koşullu kesme noktası birbirine benzer görünse de aynı şey değildir.
Gözetleme noktası **her** yazmada durur, seçim yapmaz — üç değerin üçünü de görmesinin
nedeni budur. Koşullu kesme noktası ise yalnız koşul sağlandığında durur; eşik 2 yerine 4
verilseydi, hiçbir adımda durmazdı, çünkü dizideki en büyük değer 3'tür ve hiçbiri 4'e
ulaşmaz. Gözetleme noktası "hiç kaçırma" garantisi verirken bunun bedelini her adımda
durarak öder; koşullu kesme noktası bu garantiyi vermez — yalnız koşulu tanımlanan durumu
kaçırmaz, koşulun dışında kalan her şeyi sıradan kesme noktası gibi atlar. Üçü arasındaki
seçim, aranan şeyin bir **konum** mu, her **değişim** mi, yoksa belirli bir **durum** mu
olduğuna bağlıdır.

## Sınırlayıcı Ölçüm

Bir program beklenmedik şekilde sonlandığında, o andaki bellek durumunun bir dökümü
sonradan incelenebilir — programı yeniden çalıştırmadan, çökme anındaki yığıt ve
değişken değerlerine bakmak için. Bu döküm burada üretilmiyor: bir sürecin gerçekten
çökertilmesi bu dersin kapsamı dışında, yalnız ne için kullanıldığı anlatılıyor. Kesme
noktası ve gözetleme noktası **çalışan** bir süreci durdurup gözlemler; döküm ise
**durmuş** bir sürecin geride bıraktığı durumu, süreç artık yokken okur — ikisi aynı
görünürlük sorusuna iki farklı zamanda cevap verir.

Çekirdek dökümünün asıl değeri, gözlemcinin **hazır olmadığı** anlar içindir. Kesme
noktası, gözetleme noktası ve koşullu kesme noktasının üçü de, hatayı arayan kişinin
programı önceden bir hata ayıklayıcının altında başlatmasını ya da sonradan ona
bağlanmasını gerektirir — programın ne zaman ve nerede duracağı bir ölçüde önceden
tahmin edilmelidir. Üretimde çalışan, kimsenin izlemediği bir süreç beklenmedik bir anda
çökerse, o anı yeniden yaratmak çoğu zaman mümkün olmaz; girdi, zamanlama ya da sistem
durumu bir daha aynı şekilde tekrarlanmayabilir. İşletim sistemi böyle bir çökme anında,
sürecin o anki bellek görüntüsünü — yığıt, öbek ve yazmaç değerlerini — bir dosyaya
yazabilir. Bu dosya sonradan, süreç artık çalışmıyorken bir hata ayıklayıcıya verilir ve
çökme anındaki değişken değerleri, çağrı zinciri ve durum, sanki program hâlâ o anda
duruyormuş gibi incelenebilir — yalnız artık ileri adımlanamaz, çünkü döküm tek bir
donmuş kareden ibarettir, çalışan bir süreç değildir.

Bu, dökümü kesme ve gözetleme noktalarından ayıran temel farkı ortaya koyuyor: kesme ve
gözetleme noktaları **önceden kurulmuş bir gözlem** gerektirir, döküm ise **gözlem hiç
kurulmamış olsa bile** geriye bir kayıt bırakır. Bir hata yeniden üretilebiliyorsa ve
nerede durulacağı biliniyorsa kesme ya da gözetleme noktası tercih edilir, çünkü canlı
bir süreç üzerinde adım adım ilerlemeye izin verir. Hata yalnız bir kez, öngörülemeyen
bir anda ve gözlemci hazır değilken oluyorsa, geriye kalan tek araç dökümdür — çökme
anının kendisini yeniden yaratmaya gerek kalmadan, o anın donmuş bir kopyasını sonradan
okumaktır.

Bu modelin kendi sınırı da var: burada gözlemlenen değer, kaynak kodun kendisinde
yazan değerle birebir aynı kalacak şekilde kuruldu; eniyilenmiş bir programda hata
ayıklayıcının gördüğü değer kaynaktakiyle aynı olmayabilir — bir değişken yazmaçta
tutulmuş ya da tamamen silinmiş olabilir.

Kesme noktası ile gözetleme noktası arasındaki fark, bu dersin modelinde bir dizi
uzunluğuyla sınırlı görünse de, gerçek bir programda çok daha büyük bir aralıkta
gizli kalabilir. Üç adımlık bir dizide aradaki tek değer gözden kaçtığında bunu fark
etmek görece kolaydır; yüzlerce adımdan geçen bir döngüde, kesme noktası yalnızca
girişte ve çıkışta kurulmuşsa, aradaki hatalı bir ara değer koşum boyunca hiç
görülmeden kalabilir. Gözetleme noktasının her yazmada durması bu riski ortadan
kaldırır, ama bunun bir bedeli vardır: bir değişken sık sık yazılıyorsa, program her
yazmada durduğu için çok daha yavaş ilerler. Kesme noktası ile gözetleme noktası
arasındaki seçim bu yüzden yalnız "hangisi daha çok görür" sorusu değil, "hangi
adımı görmek gerektiği önceden ne kadar biliniyor" sorusudur — hiç bilinmiyorsa
gözetleme noktasının yavaşlığı, kesme noktasının kaçırma riskine tercih edilir.

Üç durma stratejisi tek bir hata avında art arda da kullanılabilir. Bir toplam
değişkeninin beklenmedik bir noktada negatife düştüğü varsayılsın. İlk adım genellikle
gözetleme noktasıdır: değişkenin her yazıldığı an durulur, birkaç koşumdan sonra hangi
aralıkta işaretin döndüğü görülür. Aralık daraldıkça gözetleme noktasının bedeli — her
yazmada durmanın getirdiği yavaşlık — artık gerekli değildir; o aralığın başına sabit bir
kesme noktası konur ve program yalnız orada durdurulup adım adım ilerlenir. Değer negatife
dönüşü tek bir koşulda değil, girdiye bağlı birkaç farklı koşulda tekrarlıyorsa, kesme
noktası yerini koşullu kesme noktasına bırakır: durma artık "şu satıra gelince" değil
"toplam sıfırın altına düşünce" olarak tanımlanır, hangi girdinin bunu tetiklediğinden
bağımsız olarak. Bu üç aracın sırayla kullanılması rastgele değildir — her adım bir
öncekinin bulduğu bilgiyi (yaklaşık konum, sonra kesin konum, sonra durumun kendisi)
daraltarak bir sonrakine devreder. Hata üretimde ve yalnız bir kez, kimsenin izlemediği bir
anda ortaya çıkmışsa bu sıralı avlanma hiç başlamaz; elde kalan tek şey çekirdek dökümüdür,
ve o zaman soru "nerede durulmalı" değil "geride ne kayıt kaldı"dır.

## Özet

- Kesme noktası, yalnız seçilmiş adımlarda durur; iki kesme noktası arasında geçen bir
  ara değer hiç gözlemlenmez — bu dersin ölçtüğü sınıf **gözlenmeyen**.
- Gözetleme noktası her yazmada durur; kesme noktasının kaçırdığı ara değeri de görür,
  bu bir karşıtlık modelidir.
- Koşullu kesme noktası adım numarasına değil değerin kendi durumuna bakar; konum
  bilinmese de aranan durum tanımlanabiliyorsa kesme noktasının yapamadığını yapar.
- Çekirdek dökümü çalışan bir süreci durdurmaz, sonlanmış bir sürecin durumunu sonradan
  okur; önceden bir gözlem kurulmamış olsa bile geriye bir kayıt bırakır.
- Bu modelde gözlemlenen değer kaynaktaki değerle eşleşecek şekilde kuruldu; eniyilenmiş
  bir programda bu eşleşme garanti değildir.
- Hangi durma stratejisinin seçileceği aranan şeyin bir konum mu, her değişim mi, yoksa
  belirli bir durum mu olduğuna bağlıdır; gerçek bir avda üçü art arda da kullanılır —
  gözetleme noktasıyla kabaca daraltılan aralık kesme noktasıyla kesinleştirilir,
  koşula bağlı tekrar eden bir durum ise koşullu kesme noktasıyla yakalanır.

Kesme noktası ile gözetleme noktasının ikisi de programı **durdurarak** çalışır: program
duruncaya kadar normal hızında ilerler, durduğu anda bellek durumu dondurulmuş gibi
okunabilir hale gelir. Bu, iki yöntemi çekirdek dökümünden ayıran ikinci bir eksendir —
döküm sürecin kendisi artık çalışmıyorken alınan tek bir kareyken, kesme ya da gözetleme
noktası çalışan sürecin üzerinde birden çok kareyi art arda gösterebilir. Bir hatayı
ararken hangisinin daha uygun olduğu, hatanın **tek bir anda mı** yoksa **bir dizi adım
boyunca mı** ortaya çıktığına bağlıdır: tek bir çökme anı dökümle, adımlar arasında
biriken bir sapma ise durma noktalarıyla incelenir.

## Sonraki Adım

Bir değişkenin kaynakta yazdığı değerle çalışma zamanında taşıdığı değer her zaman aynı
kalmaz — bir sonraki ders bu farkın nereden geldiğini ele alıyor.
