以root身份运行时出现分段错误? [英] Segmentation fault when run as root?

查看:162
本文介绍了以root身份运行时出现分段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我从我的计算机以root身份运行时,我的c ++程序给了我一个seg故障,但是当我启动远程会话时,却没有。我的程序仅作为用户从我的电脑运行。可能是什么问题?我为嵌入式设备编写了程序,并使用它来编译:

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

我没有收到任何错误。这可能是一个国旗问题吗?我可以发布我的代码。



编辑:当我用gdb启动我的程序时,我得到:

 编程接收到的信号SIGSEGV,分段故障。 
0x40eed060来自/lib/libc.so.6
0x40eed060< strcmp + 0> ;: ldrb r2,[r0],#1


$ b
$ b
$ b

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

以下是我的代码:

  #include  
#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>

$ main(int argc,char * argv [])
{
//初始化gtkmm和maemomm:

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

//初始化D-Bus(hildon-notify需要):
DBusConnection * conn = dbus_bus_get(DBUS_BUS_SESSION,NULL);
dbus_connection_setup_with_g_main(conn,NULL);

//创建一个新通知:
Glib :: RefPtr< Hildon :: Notification> notification = Hildon :: Notification :: create(Something Happened,事情刚刚发生。,Gtk :: Stock :: OPEN);

//显示通知:
std :: auto_ptr< Glib :: Error>前;
notification-> show(ex);
if(ex.get())
{
std :: cerr<< Notification :: show()失败:<< ex-> what()<<<的std :: ENDL;
}
返回0;
}

编辑:已解决问题。程序在终端的env中需要一个DBUS_SESSION_ADDRESS。

解决方案

您可能希望在的valgrind 。我写了一个小程序,它在分配数组之外写入:

  $ valgrind ./segfault 
== 11830 = = Memcheck,一个内存错误检测器
== 11830 == Julian Seward等人版权所有(C)2002-2010和GNU GPL'd。
== 11830 ==使用Valgrind-3.6.0.SVN-Debian和LibVEX;使用-h重新运行版权信息
== 11830 ==命令:./segfault
== 11830 ==
== 11830 ==无效写入大小1
== 11830 == 0x4004BF:main(in / tmp / segfault)
== 11830 ==地址0x7feff65bf不是stack'd,malloc'd或(最近)free'd
== 11830 ==
== 11830 ==
== 11830 ==进程以信号11(SIGSEGV)的默认行为终止
== 11830 ==不在映射区域内的地址0x7FEFF65BF
== 11830 ==在0x4004BF:main(在/ tmp / segfault)
== 11830 ==如果您认为这是因为堆栈的结果
== 11830 ==您的程序主线程(不太可能,但
== 11830 ==可能),您可以尝试使用--main-stacksize =标志增加
== 11830 ==主线程堆栈的大小。
== 11830 ==此次运行中使用的主线程堆栈大小为8388608.
== 11830 ==
== 11830 == HEAP SUMMARY:
== 11830 = =在出口处使用:在0块中的0字节
== 11830 ==总堆使用情况:0分配,0释放,0字节分配
== 11830 ==
== 11830 = =所有堆块都被释放 - 没有泄漏是可能的
== 11830 ==
== 11830 ==对于检测到的和压制的错误计数,重新运行:-v
== 11830 ==错误总结:从1个上下文中的1个错误(被抑制:4从4)
分段错误

此输出中最重要的部分是:

  == 11830 ==无效写入大小1 
== 11830 == at 0x4004BF:main(in / tmp / segfault)



  int main(())可以帮助您找出涉及哪一行。 int argc,char * argv []){
char f [1];
f [-40000] ='c';
返回0;
}

另一个非常有用的工具是 gdb 。如果您将rlimits设置为允许转储内核(请参阅 setrlimit(2)以了解有关限制以及shell的手册(可能 bash(1) )以获取有关 ulimit 内置命令的详细信息),那么您可以获得一个用于 gdb

  $ ulimit -c 1000 
$ ./segfault
分段错误(code $ c):

核心转储)
$ gdb --core = core ./segfault
GNU gdb(GDB)7.2-ubuntu
自由软件基金会版权所有(c)2010
GPLv3 + :GNU GPL版本3或更高版本< http://gnu.org/licenses/gpl.html>
这是免费软件:您可以自由更改和重新分配它。
在法律允许的范围内,不存在任何担保。有关详细信息,请键入显示复制
和显示保修。
这个GDB被配置为x86_64-linux-gnu。
有关错误报告的说明,请参阅:
< http://www.gnu.org/software/gdb/bugs/> ...
从/ tmp / segfault中读取符号...(没有找到调试符号)...完成。
[新线程11951]

警告:无法读取加载映射的路径名:输入/输出错误。
读取/lib/libc.so.6...中的符号从/usr/lib/debug/lib/libc-2.12.1.so...done中读取符号。
完成。
为/lib/libc.so.6加载了符号
从/lib64/ld-linux-x86-64.so.2..读取符号从/ usr / lib / debug / lib中读取符号/ld-2.12.1.so...done。
完成。
/lib64/ld-linux-x86-64.so.2
的加载符号由`./segfault'生成。
程序终止于信号11,分段故障。 ()中的
#0 0x00000000004004bf
(gdb)bt
#0 0x00000000004004bf in main()
(gdb)quit

根据您程序的大小,您可能需要给予 1000 块以上的方式允许核心文件。如果这个程序太复杂了,那么知道调用链到达段错误可能是至关重要的信息。


My c++ program gives me a seg fault when I run as root from my computer but not when I start a remote session. My program run from my computer only as a user. What can be the problem? I wrote my program for an embedded device and I'm using this to compile:

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

I'm not getting any error. Could it be a flag problem? I can post my code.

EDIT: When I start my program with gdb I get this:

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

Backtrace give this:

(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

Here is my code:

#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;
}

EDIT: Problem solved. Program needs a DBUS_SESSION_ADDRESS in the env of the terminal.

解决方案

You might want to run your program under valgrind. I wrote a tiny program that writes outside of an allocated array:

$ 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

The most important part of this output is here:

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

The write of size 1 might help you figure out which line was involved:

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

Another very useful tool to know is gdb. If you set your rlimits to allow dumping core (see setrlimit(2) for details on the limits, and your shell's manual (probably bash(1)) for details on the ulimit built-in command) then you can get a core file for use with 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

Depending upon the size of your program, you might need to give way more than 1000 blocks to the allowed core file. If this program were remotely complicated, knowing the call chain to get to the segfault could be vital information.

这篇关于以root身份运行时出现分段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆