2014-09-06 25 views
8

Değerliğini kullanan bu küçük test programı için valgind'in neden "8 nolu başlangıç ​​boyutunun kullanılmamış değeri" hakkında şikayet ettiğini anlamaya çalışıyorum. Temel olarak "n_ucs" ucontexts yaratan ve "max_switch" zamanları için bunları değiştiren bir programdır.valgrind hatası ve ucontext. Neden "8 boyutunun başlatılmamış değerinin kullanılması"?

"Uyarı: istemci anahtarlama yığınları" nı anlıyorum? (temelde programın tamamı hakkındadır), ama gerçekten "8 boyutunun başlatılmamış değerinin kullanımı" mantığını anlamış değilim

Valgrind hatalarının yanlış pozitif olup olmadığını anlamak için biraz yardım almak isterim. eğer bu program temelde yanlış bir şey varsa. (Ben aynı mekanizmaları kullanan çok daha büyük bir program üzerinde birçoğu görüyorum, ama ben burada postalamak için minimum damıtılmış var).

Herhangi bir yardım için teşekkür ederiz.

sayesinde

Jack

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/time.h> 
#include <ucontext.h> 

#define STACK_SIZE (8*1024) 

int n_ucs = 1; 
int max_switchs = 10; 
int n_switchs = 0; 
int tid = 0; 

ucontext_t *ucs; 
static ucontext_t engine_uc; 

static void func(int arg) 
{ 
    while (n_switchs < max_switchs) { 
     int c_tid = tid; 
     int n_tid = (tid + 1) % n_ucs; 
     n_switchs++; 
     tid = n_tid; 
     swapcontext(&ucs[c_tid], &ucs[n_tid]); 
    } 
} 

int main(int argc, char **argv) 
{ 
    if (argc > 1) 
     n_ucs = atoi(argv[1]); 
    if (argc > 2) 
     max_switchs = atoi(argv[2]); 

    ucs = malloc(sizeof(ucontext_t) * n_ucs); 
    int i; 
    for (i = 0; i < n_ucs; i++) { 
     /* Create initial ucontext_t, including stack */ 
     getcontext(&ucs[i]); 
     ucs[i].uc_stack.ss_sp = malloc(STACK_SIZE); 
     ucs[i].uc_stack.ss_size = STACK_SIZE; 
     ucs[i].uc_stack.ss_flags = 0; 
     ucs[i].uc_link = &engine_uc; 
     makecontext(&ucs[i], (void (*)())func, 1, i); 
    } 

    /* jump to the first uc */ 
    swapcontext(&engine_uc, &ucs[tid]); 

    /* destroy stacks */ 
    for (i = 0; i < n_ucs; i++) 
     free(ucs[i].uc_stack.ss_sp); 
    free(ucs); 
    return 0; 
} 

gcc main.c ile derlemek ve ./a.out 2 2

gcc -v

ile çalışacak

Yerleşik özellikleri kullanma. COLLECT_GCC = gcc COLLECT_LTO_WRAPPER =/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-sarıcı Hedef: x86_64-linux-gnu Aşağıdakilerle Yapılandırıldı: ../src/configure -v --with-pkgversion = 'Ubuntu 4.8.2-19ubuntu1' --with-bugurl = dosya: ///usr/share/doc/gcc-4.8/README.Bugs --enable-languages ​​= c, C++, java, go, d, fortran, objc, obj-C++ --prefix =/usr --program-sonek = -4.8 --enable-shared --enable-linker-build-id --libexecdir =/usr/lib --without-dahil-gettext - enable-threads = posix --with-gxx-include-dir =/usr/include/C++/4.8 --libdir =/usr/lib --enable-nls --with-sysroot =/--enable-clocale = gnu --enable-libstdcxx-debug --enable-libstdcxx-time = evet --enable-gnu-benzersiz nesne --disable libmudflap --enable-eklenti --with-system-zlib --disable-tarayıcı-eklenti - -enable-java-awt = gtk --enable-gtk-cairo --with-java-home =/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-ev --with-jvm-root-dir =/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 - çerçeve h-jvm-jar-dir =/usr/lib/jvm-export/java-1.5.0-gcj-4.8-amd64 -with-arch-directory = amd64 -with-ecj-jar =/usr/paylaşım/java/eclipse-ecj.jar --enable-objc-gc --enable-çokarch --disable-werror --with-arch-32 = i686 --with-abi = m64 --with-multilib-list = m32, m64, mx32 --with-tune = genel --enable-kontrol = serbest bırakma --build = x86_64-linux-gnu --host = x86_64-linux-gnu --target = x86_64-linux-gnu Konu modeli: posix gcc sürümü 4.8.2 (Ubuntu 4.8.2-19ubuntu1)

ldd version

ldd (Ubuntu EGLIBC 2.19-0ubuntu6.3) 2.19 Copyright (C) 2014 Free Software Foundation, Inc. Bu ücretsiz bir yazılımdır ; Kopyalama koşulları için kaynağına bakın. Hiçbir garanti yoktur; SATILABİLİRLİK veya BELİRLİ BİR AMACA UYGUNLUK İÇİN BAŞKA DEĞİL. Roland McGrath ve Ulrich Drepper tarafından yazıldı.

valgrind --track-origins=yes ./a.out 2 2 
==21949== Memcheck, a memory error detector 
==21949== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==21949== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info 
==21949== Command: ./a.out 2 2 
==21949== 
==21949== Warning: client switching stacks? SP change: 0xffefffdd8 --> 0x51ff7b8 
==21949==   to suppress, use: --max-stackframe=68616717856 or greater 
==21949== Use of uninitialised value of size 8 
==21949== at 0x400738: func (main.c:25) 
==21949== by 0x4E58EC4: (below main) (libc-start.c:287) 
==21949== Uninitialised value was created by a stack allocation 
==21949== at 0x4E7E445: swapcontext (swapcontext.S:92) 
==21949== 
==21949== Conditional jump or move depends on uninitialised value(s) 
==21949== at 0x4E807A7: __start_context (__start_context.S:37) 
==21949== by 0x4E58EC4: (below main) (libc-start.c:287) 
==21949== Uninitialised value was created by a stack allocation 
==21949== at 0x4E7E445: swapcontext (swapcontext.S:92) 
==21949== 
==21949== Syscall param rt_sigprocmask(set) contains uninitialised byte(s) 
==21949== at 0x4E7E0EC: setcontext (setcontext.S:47) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== Uninitialised value was created by a stack allocation 
==21949== at 0x4E7E445: swapcontext (swapcontext.S:92) 
==21949== 
==21949== Use of uninitialised value of size 8 
==21949== at 0x4E7E0F5: setcontext (setcontext.S:54) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== Uninitialised value was created by a stack allocation 
==21949== at 0x4E7E445: swapcontext (swapcontext.S:92) 
==21949== 
==21949== Use of uninitialised value of size 8 
==21949== at 0x4E7E0FE: setcontext (setcontext.S:56) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== by 0x4E807AD: __start_context (__start_context.S:39) 
==21949== Uninitialised value was created by a stack allocation 
==21949== at 0x4E7E445: swapcontext (swapcontext.S:92) 
==21949== 
==21949== Warning: client switching stacks? SP change: 0x51ff7c0 --> 0xffefffde0 
==21949==   to suppress, use: --max-stackframe=68616717856 or greater 
==21949== 
==21949== HEAP SUMMARY: 
==21949==  in use at exit: 0 bytes in 0 blocks 
==21949== total heap usage: 3 allocs, 3 frees, 18,256 bytes allocated 
==21949== 
==21949== All heap blocks were freed -- no leaks are possible 
==21949== 
==21949== For counts of detected and suppressed errors, rerun with: -v 
==21949== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0) 
+1

sizin işaretçileri 64-bit (8 bayt) vardır, bir 64-bit mimarisi üzerinde çalışan varsayarak: Bu doğru kod burada https://github.com/lu-zero/valgrind/blob/master/memcheck/tests/linux/stack_changes.c

bir örnek okuyun. Ayrıca '' var' – clearlight

+2

'malloc() ',' calloc()' dan farklı olarak, bellek ayırmak için [calloc() '] (https://linux.die.net/man/3/calloc) kullanarak düşünün. 'atanmış belleğinizi dolaylı olarak sıfırlar (calloc() 'ı unutmayın; 2. argümanı alır, [manpage] (https://linux.die.net/man/3/calloc)) ya da'() 'döngü veya bunu yapmak için bzero()' veya 'memset()' kullanın. – clearlight

cevap

1

Hala tam olarak valgrind bu başlatılmamış hataları tam gösteriyor neden anlamıyorum ama o ben şu ana kadar anlamış anlatmaya en iyi görüntüyü vereceğim;

Program, valgrind yoluyla ve swapcontext (3) ve getcontext (3) sayfalarındaki bilgileri temel alarak program üzerinde çalışıp analiz ederken, bazı içerik takaslarını algılamıyor (swapcontext için yığın göstergesinde değişiklik göremiyorum) [çağrının numarası] yığını kim:

Yani işlev çağrısında, sanırım işlev çağrısı izidir tid 1'e tid 0 ve tid 1'den swapcontext geri 0)

aşağıda oku TID için bunun gibi bir şey:

ana: swapcontext (ana, günde üç kez 0) ->

ana [tid 0 '1 fonk çağrı]: fonk() ->

tid 0: swapcontext (tid 0, günde üç kez 1) -> { Yığın => tiod 0}

tid 1: fonk() ->

swapcontext (tid 1, günde üç kez 0) -> {Yığın => tiod 1}

tid 0 [2. arama]: fonk() - hemen>

dönüş yana n_switchs = 2 ->

açılır günde üç kez 0 [2. arama]: tid 1'in yığından fonk() yığın çerçevesi ->{ tid 0

} valgrind göre 1 başlatılmamış erişim [2. arama]: fonk() tamamlandıktan -> kontrol uc_link; engine_uc bulur (ana bağlamı) set var ->

burada şeylere itibaren

benim için belirsiz olsun ancak aşağıdaki muhtemel iz gibi görünüyor:

sıfırlar sigprocmask ->{2 Başlatılmamış erişim} setcontext() ler tekrar ana bağlamına ->{3 Uinitialized erişim?} {Stack => ana}

> Uc_link kontrol - fonk() de, çünkü n_switchs olarak tamamlanır = 2: dönüşünde

[tid 0 '1 çağrı] için yığın çerçeve ana ana [tid 0' 1 çağrı] stack->

dan attı ; engine_uc'u tekrar bulur -> sıfırlar sigprocmask -> {başlatılmamış erişim değil?} dönüşünde

ana için yığın çerçevesi swapcontext() ana yığından uzattı ->

setcontext() ana bağlamda geri s ->{4 başlatılmamış erişim }? {Yığın => ana}

biz) (ana, ücretsiz malzeme ve çıkış

0 gel

Bazı Referanslar:

https://www.gnu.org/software/libc/manual/html_node/System-V-contexts.html http://www.cs.uwm.edu/classes/cs315/Bacon/Lecture/HTML/ch10s07.html

Not: Bu tam bir cevap değil ama yorum bölümünde bu kadar uzun bir açıklama göndermek istemediğini biliyorum; bu nedenle buraya gönderildi.

1

Yığın değişikliği ile ilgili bilgi vermeniz gerekir.

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/time.h> 
#include <ucontext.h> 
#include <valgrind/valgrind.h> 

#define STACK_SIZE (8*1024) 

int n_ucs = 1; 
int max_switchs = 10; 
int n_switchs = 0; 
int tid = 0; 

ucontext_t *ucs; 
static ucontext_t engine_uc; 

void func(int arg) 
{ 
    while (n_switchs < max_switchs) { 
     int c_tid = tid; 
     int n_tid = (tid + 1) % n_ucs; 
     n_switchs++; 
     tid = n_tid; 
     swapcontext(&ucs[c_tid], &ucs[n_tid]); 

    } 
} 

int main(int argc, char **argv) 
{ 
    if (argc > 1) 
     n_ucs = atoi(argv[1]); 
    if (argc > 2) 
     max_switchs = atoi(argv[2]); 

    ucs = malloc(sizeof(ucontext_t) * n_ucs); 

    //store the VALGRIND_STACK_REGISTER return values 
    int* valgrind_ret = malloc(n_ucs*sizeof(int)); 

    int i; 
    for (i = 0; i < n_ucs; i++) { 
     /* Create initial ucontext_t, including stack */ 
     getcontext(&ucs[i]); 

     //pass stack to valgrind 
     void* mystack = malloc(STACK_SIZE); 
     VALGRIND_STACK_REGISTER(mystack, mystack + STACK_SIZE); 

     ucs[i].uc_stack.ss_sp = mystack; 
     ucs[i].uc_stack.ss_size = STACK_SIZE; 
     ucs[i].uc_stack.ss_flags = 0; 
     ucs[i].uc_link = &engine_uc; 
     makecontext(&ucs[i], (void (*)())func, 1, i); 
    } 

    /* jump to the first uc */ 
    swapcontext(&engine_uc, &ucs[tid]); 

    /* destroy stacks */ 
    for (i = 0; i < n_ucs; i++) { 
     //valgrind stack deregister 
     VALGRIND_STACK_DEREGISTER(valgrind_ret[i]); 

     free(ucs[i].uc_stack.ss_sp); 
    } 
    free(ucs); 
    return 0; 
}