19 Mart 2018 Pazartesi

valgrind track-origins seçeneği

Giriş
track-origins seçeneğini kullanırsak, ilklendirilmemiş değişkenin nerede olduğunu görebiliriz. Eğer bu seçeneği kullanmadıysak hata raporunun en sonunda şöyle bir satır görebiliriz.
==9145== Use --track-origins=yes to see where uninitialised values come from
Bu seçeneği kullanırsak valgrind şöyle hata verir.
==3076== Conditional jump or move depends on uninitialised value(s)
Örnek
Elimizde şöyle bir kod olsun.
#include <iostream>
using namespace std;

int main() {
    int x;
    cout << x << endl;
    return 0;
}
Şöyle yaparız
$ valgrind --track-origins=yes ./a.out
==4950== Memcheck, a memory error detector
==4950== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4950== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4950== Command: ./a.out
==4950== 
==4950== Conditional jump or move depends on uninitialised value(s)
...
==4950==  Uninitialised value was created by a stack allocation
==4950==    at 0x400757: main (t.cpp:3)
==4950== 
Örnek
Elimizde şöyle bir kod olsun. x ilklendirilmemiş olarak kullanılıyor. Dolayısıyla valgrind hata verir.
#include <functional>
#include <iostream>

std::function<void()> callback;

void foo()
{
   int x;
   callback = [&]() { if (x > 5) std::cout << "hi"; };
}

int main()
{
   foo();
   callback();
}
Örnek
Elimizde şöyle bir kod olsun.
ListNodePtr convertBSTtoLinkedList(TreeNodePtr root)
{
  ListNodePtr list = malloc(sizeof(struct ListNode));
  list->key = root->key;
  if (root->right != NULL)
  {
    list->next = convertBSTtoLinkedList(root->right);    //line 80
  }
  ...
  return list;
}   
Bu kodda root->right == NULL durumunda list->next'e değer atanmıyor ve bu alan kodda kullanıldığı için valgrind uyarı veriyor.
Örnek
uninitialized data kopyalanırsa valgrind ilginç bir şekilde uyarı vermiyor. Açıklaması şöyle
It is important to understand that your program can copy around junk (uninitialised) data as much as it likes. Memcheck observes this and keeps track of the data, but does not complain. A complaint is issued only when your program attempts to make use of uninitialised data in a way that might affect your program's externally-visible behaviour.
Şöyle bir örnek verebiliriz. Burada memcpy paddingden dolayı belki ilklendirilmemiş belleği de kopyalıyor.
struct {
    char a;
    int b;
} s1, s2;

s1.a = '.';
s1.b = 31337;

memcpy (&s2, &s1, sizeof(s1));

Hiç yorum yok:

Yorum Gönder