Geliştirici Araçları
TEKNİK REHBER GELİŞTİRİCİ ARAÇLARI TRACING 2026

strace —
syscall tracer.

ptrace mekanizmasıyla her sistem çağrısını yakala. Dosya erişimlerini, ağ bağlantılarını ve bellek işlemlerini izle. "Permission denied" hatalarından embedded busybox strace kullanımına.

00 strace nedir — ptrace mekanizması

strace, Linux'un ptrace(2) sistem çağrısı üzerine inşa edilmiş bir izleme aracıdır. Kaynak kodu olmayan ya da erişilemeyen binary'lerin davranışını anlamak için ideal yöntemdir.

Bir süreç her sistem çağrısı yapmak istediğinde kernel'a geçiş yapar. ptrace mekanizması bu geçişe "hook" eklemeye izin verir: strace, izlenen süreci her syscall girişinde ve çıkışında durdurur, argümanları ve dönüş değerini kaydeder, sonra süreci devam ettirir.

ptrace ek yükü

bash
# strace ek yükünü ölç
time ls /
# real  0m0.004s

time strace ls / 2>/dev/null
# real  0m0.018s  <-- ~4-5x yavaş

# Yüksek frekanslı uygulamalarda strace ciddi yavaşlamaya yol açar
# Sadece debug amacıyla kullanılmalı, üretimde asla
bash — kurulum
# Debian/Ubuntu
sudo apt install strace

# ARM embedded: Buildroot'ta CONFIG_STRACE=y
# Yocto: IMAGE_INSTALL += "strace"

# Sürümü kontrol et
strace --version
# strace -- version 5.16

01 Temel kullanım — yeni süreç ve -p PID attach

strace ya yeni bir süreci başlatır ya da çalışan bir sürece bağlanır. Çıktı varsayılan olarak stderr'e yazılır.

bash
# Yeni süreç başlat ve izle
strace ls /tmp

# Çalışan sürece bağlan (root gerekebilir)
strace -p 1234

# İsimle bağlan (pidof ile)
strace -p $(pidof nginx)

# Birden fazla PID izle
strace -p 1234 -p 1235
strace çıktısı — ls /tmp
execve("/bin/ls", ["ls", "/tmp"], 0x7ffe... /* 23 vars */) = 0
brk(NULL)                               = 0x55a8f2b00000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f3a1c200000
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=87432, ...}) = 0
mmap(NULL, 87432, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f3a1c1ec000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
...
openat(AT_FDCWD, "/tmp", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
getdents64(3, /* 14 entries */, 32768)  = 448
write(1, "core.myapp.1234  sensor.log  ...", 34) = 34
close(3)                                = 0
exit_group(0)                           = ?

Her satır: syscall adı, argümanlar ve dönüş değeri (= 0 başarı, negatif değer hata). Hata durumlarında errno sembolik ismi de görünür: = -1 ENOENT (No such file or directory)

02 -e trace= — filtreleme

Filtresiz strace çıktısı çok gürültülüdür. -e trace= ile ilgilenilen syscall kategorilerini seçebilirsiniz.

bash — kategori filtreleri
# Sadece dosya işlemleri
strace -e trace=file myapp
# open, openat, read, write, close, stat, lstat, access, unlink...

# Sadece ağ işlemleri
strace -e trace=network myapp
# socket, connect, bind, listen, accept, send, recv, sendto...

# Sadece bellek işlemleri
strace -e trace=memory myapp
# mmap, munmap, mprotect, brk, madvise...

# Sadece sinyal işleme
strace -e trace=signal myapp

# Sadece süreç yönetimi
strace -e trace=process myapp
# execve, fork, clone, wait, exit...

# Belirli syscall'ları seç
strace -e trace=openat,read,write,close myapp

# Belirli syscall'ları hariç tut
strace -e trace='!mmap,mprotect,munmap' myapp
strace -e trace=file çıktısı
openat(AT_FDCWD, "/etc/sensor.conf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/default/sensor.conf", O_RDONLY) = 3
read(3, "[sensor]\nport=/dev/ttyS0\nbaud=11", 4096) = 78
close(3)                                = 0
openat(AT_FDCWD, "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NONBLOCK) = 4
# /etc/sensor.conf bulunamadı → fallback /etc/default/sensor.conf açıldı

03 -c — syscall istatistikleri

-c bayrağı, program sonunda hangi syscall'ın kaç kez çağrıldığını ve ne kadar süre harcadığını özetler. Performans darboğazlarını bulmak için hızlı bir yöntemdir.

bash
# İstatistik modu (-c)
strace -c myapp

# İstatistik + belirli kategori
strace -c -e trace=file myapp
strace -c çıktısı
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 68.42    0.041234        1234        33           read
 15.31    0.009234          89       104        12 openat
  8.12    0.004899         122        40           write
  4.22    0.002543          36        71           close
  1.98    0.001193          23        52           fstat
  0.87    0.000524         524         1           execve
  0.62    0.000374          17        22           mmap
  0.27    0.000163          20         8           mprotect
  0.19    0.000117         117         1           munmap
------ ----------- ----------- --------- --------- ----------------
100.00    0.060281                   332        12 total

# read: toplam sürenin %68'i → I/O darboğazı var!

04 -tt, -T — zaman damgası

Zaman damgaları, hangi syscall'ın ne kadar sürdüğünü ve olayların sırasını anlamak için kritiktir.

bash
# -t: saniye cinsinden zaman damgası
strace -t myapp

# -tt: mikrosaniye hassasiyetinde
strace -tt myapp

# -ttt: Unix epoch (floating point)
strace -ttt myapp

# -T: her syscall'ın süresi (sonuna eklenir)
strace -T myapp

# Birlikte kullanım
strace -tt -T myapp
strace -tt -T çıktısı
14:23:45.123456 openat(AT_FDCWD, "/dev/i2c-1", O_RDWR) = 5 <0.000234>
14:23:45.123721 ioctl(5, I2C_SLAVE, 0x48)              = 0 <0.000089>
14:23:45.123834 write(5, "\x01\x00", 2)                = 2 <0.000156>
14:23:45.270000 read(5, "\x0c\x80", 2)                 = 2 <0.146123>
# read süresi 0.146s → ADC conversion time (I2C sensör okuma)
14:23:45.270200 close(5)                               = 0 <0.000045>

05 -f — fork / exec izleme

Daemon'lar ve shell scriptleri genellikle alt süreçler oluşturur. -f bu alt süreçleri de izler.

bash
# -f: fork/clone ile oluşturulan tüm çocuk süreçleri izle
strace -f myapp

# -ff: her süreci ayrı dosyaya yaz (PID ile)
strace -ff -o /tmp/trace myapp
# /tmp/trace.1234  (ana süreç)
# /tmp/trace.1235  (fork'lanan çocuk)
# /tmp/trace.1236  (exec ile başlatılan süreç)

# Sistem başlangıcı izleme (PID 1 — init/systemd)
strace -p 1 -f -e trace=process 2>&1 | head -50
strace -f çıktısı
1234  clone(child_stack=NULL, flags=CLONE_CHILD_...) = 1235
1235  execve("/usr/bin/sensor_helper", ...) = 0
1235  openat(AT_FDCWD, "/dev/i2c-1", O_RDWR) = 3
1234  wait4(1235, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 1235
# Her satır PID ile başlar

06 -o, -k — dosyaya yaz ve stack trace

Uzun süre çalışan süreçler için çıktıyı dosyaya yönlendirmek ve her syscall'da stack trace almak.

bash
# -o: çıktıyı dosyaya yaz (stderr değil)
strace -o /tmp/myapp_trace.log myapp

# Hem ekranda görüntüle hem dosyaya yaz
strace myapp 2>&1 | tee /tmp/myapp_trace.log

# -k: her syscall için kullanıcı alanı stack trace ekle
# (strace 5.0+ gerekir, DWARF debug info yardımcı olur)
strace -k myapp 2>&1 | head -30
strace -k çıktısı
openat(AT_FDCWD, "/dev/i2c-1", O_RDWR) = 3
 > /lib/arm-linux-gnueabihf/libc.so.6(open64+0x20) [0x76f3e200]
 > myapp(i2c_open+0x18) [0x10498]
 > myapp(sensor_init+0x34) [0x104e8]
 > myapp(main+0x24) [0x10544]
# Hangi fonksiyon zincirinin bu syscall'ı tetiklediği görünür

07 Pratik: dosya erişimi ve network analizi

İki yaygın embedded senaryo: binary'nin hangi konfigürasyon dosyalarını aradığını bulmak ve ağ bağlantısını analiz etmek.

Senaryo 1: binary hangi dosyaları açıyor?

bash
# Tüm dosya açma işlemlerini listele
strace -e trace=openat,open myapp 2>&1 | grep -v "= -1"
# Başarısız açmaları filtrele, sadece başarılı olanları göster

# Hangi dosyaları açmaya çalışıp bulamadı?
strace -e trace=openat myapp 2>&1 | grep ENOENT
# openat(..., "/etc/sensor.conf", ...) = -1 ENOENT
# openat(..., "/var/lib/sensor/config", ...) = -1 ENOENT

# Sıralı liste (unique dosyalar)
strace -e trace=openat myapp 2>&1 | \
  grep -oP '"[^"]*"' | sort -u

Senaryo 2: ağ bağlantısı analizi

bash
# Network syscall'larını izle
strace -e trace=network myapp 2>&1 | head -30
strace -e trace=network çıktısı
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 5
connect(5, {sa_family=AF_INET, sin_port=htons(1883),
            sin_addr=inet_addr("192.168.1.10")}, 16) = -1 ECONNREFUSED
# MQTT broker 192.168.1.10:1883'e bağlanmaya çalışıyor ama reddedildi
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) = 5
sendto(5, "...", 48, 0, {sa_family=AF_INET,
       sin_port=htons(53), sin_addr=inet_addr("8.8.8.8")}, 16) = 48
# DNS sorgusu 8.8.8.8:53'e

08 Embedded: busybox strace + "permission denied" debug

Kaynak kısıtlı embedded sistemlerde busybox strace kullanılır. Permission denied hatalarını debug etmek için strace vazgeçilmezdir.

busybox strace

bash — embedded hedef
# busybox strace (tam strace'in alt kümesi)
busybox strace myapp

# Desteklenen bayraklar genellikle: -f, -e, -o, -p
busybox strace --help

# Buildroot'ta tam strace eklemek için:
# BR2_PACKAGE_STRACE=y

# Yocto'da:
# IMAGE_INSTALL:append = " strace"

# Statik strace indir ve SCP ile hedefe kopyala
# (eğer rootfs'e ekleyemiyorsan)
scp strace-arm-static root@192.168.1.100:/tmp/
/tmp/strace-arm-static myapp

Senaryo: "permission denied" debug

bash
# Program "permission denied" veriyor ama nerede?
./sensor_daemon
# Error: Permission denied

# strace ile hangi işlemin hata verdiğini bul
strace -e trace=file ./sensor_daemon 2>&1 | grep EACCES
çıktı
openat(AT_FDCWD, "/dev/i2c-1", O_RDWR) = -1 EACCES (Permission denied)
# /dev/i2c-1 açılamıyor!

# İzinleri kontrol et
ls -la /dev/i2c-1
# crw------- 1 root root 89, 1  /dev/i2c-1
# Sadece root erişebiliyor

# Çözüm 1: i2c grubuna ekle
sudo usermod -aG i2c $USER
sudo chown root:i2c /dev/i2c-1
sudo chmod g+rw /dev/i2c-1

# Çözüm 2: udev kuralı (kalıcı)
echo 'SUBSYSTEM=="i2c-dev", MODE="0660", GROUP="i2c"' \
  > /etc/udev/rules.d/99-i2c.rules
udevadm control --reload-rules
DİKKAT — ptrace kısıtlamaları

Güvenli Linux yapılandırmalarında (Yama: Yama seccomp, SELinux veya AppArmor) ptrace varsayılan olarak kısıtlanmış olabilir. echo 0 > /proc/sys/kernel/yama/ptrace_scope komutu (root olarak) ptrace'i geçici olarak açar. Üretim sistemlerinde dikkatli olun.