2011-06-03 129 views
1

當我從我的電腦以root身份運行時,我的C++程序給了我一個seg故障,但是當我啓動一個遠程會話時,卻沒有。我的程序僅作爲用戶從我的電腦運行。可能是什麼問題?我寫了一個嵌入式設備的程序,我用它來編譯:以root身份運行時出現分段錯誤?

gcc -Werror notify.cc -o notify `pkg-config --libs --cflags gtk+-2.0 hildon-notifymm hildonmm hildon-fmmm' 

我沒有收到任何錯誤。這可能是一個國旗問題嗎?我可以發佈我的代碼。

編輯:當我開始我的程序使用gdb我得到這個:

Program received signal SIGSEGV, Segmentation fault. 
0x40eed060 in strcmp() from /lib/libc.so.6 
0x40eed060 <strcmp+0>: ldrb r2, [r0], #1 

回溯給這個:

(gdb) backtrace 
#0 0x40eed060 in strcmp() from /lib/libc.so.6 
#1 0x40b7f190 in dbus_set_g_error() 
from /usr/lib/libdbus-glib-1.so.2 
#2 0x40b7d060 in dbus_g_bus_get() from /usr/lib/libdbus-glib-1.so.2 
#3 0x400558ec in notify_init() from /usr/lib/libnotify.so.1 
#4 0x4004a240 in Notify::init(Glib::ustring const&)() 
from /usr/lib/libnotifymm-1.0.so.7 
#5 0x40033794 in Hildon::notify_init(Glib::ustring const&)() 
from /usr/lib/libhildon-notifymm-1.0.so.1 

這裏是我的代碼:

#include <hildonmm.h> 
#include <hildon-notifymm.h> 
#include <hildon/hildon-notification.h> 
#include <libnotifymm/init.h> 
#include <gtkmm/stock.h> 
#include <dbus/dbus.h> 
#include <dbus/dbus-glib.h> 
#include <dbus/dbus-glib-lowlevel.h> 
#include <iostream> 

int main(int argc, char *argv[]) 
{ 
// Initialize gtkmm and maemomm: 

Hildon::init(); 
Hildon::notify_init("Notification Example"); 

// Initialize D-Bus (needed by hildon-notify): 
DBusConnection* conn = dbus_bus_get(DBUS_BUS_SESSION, NULL); 
dbus_connection_setup_with_g_main(conn, NULL); 

// Create a new notification: 
Glib::RefPtr<Hildon::Notification> notification = Hildon::Notification::create("Something Happened", "A thing has just happened.", Gtk::Stock::OPEN); 

// Show the notification: 
std::auto_ptr<Glib::Error> ex; 
notification->show(ex); 
if(ex.get()) 
{ 
std::cerr << "Notification::show() failed: " << ex->what() << std::endl; 
} 
return 0; 
} 

編輯:問題解決了。程序在終端的env中需要一個DBUS_SESSION_ADDRESS。

回答

4

您可能想要在valgrind下運行您的程序。我寫了一個小程序,外面寫一個分配的數組:

$ valgrind ./segfault 
==11830== Memcheck, a memory error detector 
==11830== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. 
==11830== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info 
==11830== Command: ./segfault 
==11830== 
==11830== Invalid write of size 1 
==11830== at 0x4004BF: main (in /tmp/segfault) 
==11830== Address 0x7feff65bf is not stack'd, malloc'd or (recently) free'd 
==11830== 
==11830== 
==11830== Process terminating with default action of signal 11 (SIGSEGV) 
==11830== Access not within mapped region at address 0x7FEFF65BF 
==11830== at 0x4004BF: main (in /tmp/segfault) 
==11830== If you believe this happened as a result of a stack 
==11830== overflow in your program's main thread (unlikely but 
==11830== possible), you can try to increase the size of the 
==11830== main thread stack using the --main-stacksize= flag. 
==11830== The main thread stack size used in this run was 8388608. 
==11830== 
==11830== HEAP SUMMARY: 
==11830==  in use at exit: 0 bytes in 0 blocks 
==11830== total heap usage: 0 allocs, 0 frees, 0 bytes allocated 
==11830== 
==11830== All heap blocks were freed -- no leaks are possible 
==11830== 
==11830== For counts of detected and suppressed errors, rerun with: -v 
==11830== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4) 
Segmentation fault 

該輸出的最重要的部分是在這裏:

==11830== Invalid write of size 1 
==11830== at 0x4004BF: main (in /tmp/segfault) 

write of size 1可以幫助你找出哪一行參與:

int main(int argc, char *argv[]) { 
    char f[1]; 
    f[-40000]='c'; 
    return 0; 
} 

另一個非常有用的工具是gdb。如果您設置rlimits允許傾倒的核心(見setrlimit(2)有關限制的詳細信息,以及你的shell對內置命令的ulimit細節手冊(可能bash(1))),那麼你可以使用的核心文件,gdb

$ ulimit -c 1000 
$ ./segfault 
Segmentation fault (core dumped) 
$ gdb --core=core ./segfault 
GNU gdb (GDB) 7.2-ubuntu 
Copyright (C) 2010 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-linux-gnu". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>... 
Reading symbols from /tmp/segfault...(no debugging symbols found)...done. 
[New Thread 11951] 

warning: Can't read pathname for load map: Input/output error. 
Reading symbols from /lib/libc.so.6...Reading symbols from /usr/lib/debug/lib/libc-2.12.1.so...done. 
done. 
Loaded symbols for /lib/libc.so.6 
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.12.1.so...done. 
done. 
Loaded symbols for /lib64/ld-linux-x86-64.so.2 
Core was generated by `./segfault'. 
Program terminated with signal 11, Segmentation fault. 
#0 0x00000000004004bf in main() 
(gdb) bt 
#0 0x00000000004004bf in main() 
(gdb) quit 

根據程序的大小,您可能需要讓1000塊以上的方式訪問允許的核心文件。如果這個程序非常複雜,那麼瞭解呼叫鏈接到段錯誤可能是至關重要的信息。

6

問題是你在某處調用了未定義的行爲。未定義的行爲可以在不同的機器上表現不同,在同一臺機器上運行不同的表現。你必須找到你讓野蠻指針發生的地方並處理它。

當你作爲一個有限的用戶運行時,你很可能會得到「幸運」,並且你的進程的頁面權限被設置爲允許任何無效的內存訪問,或者你有一些根特定的代碼僅在用戶模式下運行時沒有被達到。

2

如果沒有看到任何代碼就很難說具體的東西,所以我給你一些一般的建議:學會使用你的調試器(可能是gdb),並嘗試在調試器下重現 的故障。如果你幸運的話,段錯將仍然在調試器下發生, 你會得到一個堆棧跟蹤,顯示它失敗的地方,這會給你一個起點,讓你回到真正的源頭問題。

如果你不走運,如果你使用調試支持進行編譯,或者 在gdb下運行,問題可能會消失。在這種情況下,您必須訴諸代碼檢查,並清除您的代碼中的任何未定義行爲(例如,野生或未初始化的指針,如Billy ONeal建議的 )。

2

設置ulimit -c unlimited

運行你的程序,讓它崩潰。它現在應該是核心轉儲。

運行gdb <program-name> core

如果使用bt(回溯)命令,它應該給你當碰撞發生的事情是一個好主意。這應該會幫助你解決它。

相關問題