Nasıl gcc benim C çöker app bir stacktrace oluşturmak için
C benim app çöküyor bir stacktrace oluşturmak istiyorum.
Ben zaten bu sorulan ama benim ihtiyaçları netleştirmek gerekli sanırım.
Benim uygulama birçok farklı kullanıcı tarafından çalıştırılır ve aynı zamanda, Windows ve Macintosh ( sürüm gcc kullanarak derlenmiş) Linux üzerinde çalışır.
İsterim benim program yapabilmek için oluşturmak bir yığın izleme, çöküyor ve bir dahaki sefere kullanıcı çalıştırın, onu sorayım eğer Tamam gönder yığın izleme için bana ben izini sürmek için sorun. Bana bilgi göndermek halledebilirim ama izleme dize oluşturmak için nasıl bilmiyorum. Herhangi bir fikir?
CEVAP
Linux ve sanırım Mac OS X kullanıyorsanız gcc, ya da herhangi bir derleyici kullanan abone olarak giriş kullanabilirsiniz geri iz() fonksiyonları execinfo.h
Baskı stacktrace ve çıkış incelikle olsun segment hatası. Belgeler in the libc manual bulunabilir.
İşte segfaults SIGSEGV
işleyicisi yükler ve stderr
için bir stacktrace yazdıran örnek bir program. baz()
işlevi burada işleyicisi tetikleyen segfault neden olur:
#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void handler(int sig) {
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
void baz() {
int *foo = (int*)-1; // make a bad pointer
printf("%d\n", *foo); // causes segfault
}
void bar() { baz(); }
void foo() { bar(); }
int main(int argc, char **argv) {
signal(SIGSEGV, handler); // install our handler
foo(); // this will call foo, bar, and baz. baz segfaults.
}
-g -rdynamic
ile derleme olur abone olarak giriş güzel bir stacktrace yapmak için kullanabileceğiniz çıktı, simge bilgi:
$ gcc -g -rdynamic ./test.c -o test
Bu çıkış alır yürütme:
$ ./test
Error: signal 11:
./test(handler 0x19)[0x400911]
/lib64/tls/libc.so.6[0x3a9b92e380]
./test(baz 0x14)[0x400962]
./test(bar 0xe)[0x400983]
./test(foo 0xe)[0x400993]
./test(main 0x28)[0x4009bd]
/lib64/tls/libc.so.6(__libc_start_main 0xdb)[0x3a9b91c4bb]
./test[0x40086a]
Bu yük modül, ofset gösterir, ve yığındaki her bir çerçeve gelen işlevi. Burada gördüğünüz sinyal işleyicisi üstüne yığın, ve C kütüphanesi fonksiyonları önce main
ek olarak main
, foo
, bar
, ve baz
.
Nasıl benim için bir SQL dizesi oluştu...
Nasıl gıt iptalleri için benim tercihi...
Nasıl alfa-sayısal rasgele bir dize ol...
Nasıl bir dosyanın içeriğini bir Java ...
Nasıl pi benim hesaplama doğru olup ol...