简体   繁体   English

以root身份运行时出现分段错误?

[英]Segmentation fault when run as root?

My c++ program gives me a seg fault when I run as root from my computer but not when I start a remote session.当我从计算机以 root 身份运行时,我的 c++ 程序给了我一个 seg 错误,但当我启动远程 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:编辑:当我用 gdb 开始我的程序时,我得到了这个:

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.程序在终端的环境中需要一个 DBUS_SESSION_ADDRESS。

The problem is that you've invoked undefined behavior somewhere.问题是您在某处调用了未定义的行为。 Undefined behavior can behave differently on different machines, different runs on the same machine, whatever.未定义的行为在不同的机器上可能表现不同,在同一台机器上的不同运行等等。 You've got to find where you let a wild pointer happen and deal with it.你必须找到让野指针发生的地方并处理它。

Most likely you're just getting "lucky" when running as a limited user and either the page permissions on your process are set to allow whatever invalid memory access you're getting, or you have some root-specific code which isn't being reached when run in usermode only.很可能您只是在以受限用户身份运行时变得“幸运”,并且您的进程的页面权限设置为允许您获得任何无效的 memory 访问,或者您有一些特定于 root 的代码不是仅在用户模式下运行时达到。

You might want to run your program under valgrind .您可能希望在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:这个output最重要的部分在这里:

==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: write of size 1可能会帮助您确定涉及哪一行:

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

Another very useful tool to know is gdb .另一个非常有用的工具是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 :如果您将 rlimits 设置为允许转储核心(有关限制的详细信息,请参阅setrlimit(2) ,有关ulimit内置命令的详细信息,请参阅您的 shell 手册(可能是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

Depending upon the size of your program, you might need to give way more than 1000 blocks to the allowed core file.根据程序的大小,您可能需要为允许的核心文件让路超过1000块。 If this program were remotely complicated, knowing the call chain to get to the segfault could be vital information.如果这个程序非常复杂,那么了解调用链以获取段错误可能是至关重要的信息。

It's hard to say anything specific without seeing any code, so I'll give you some general advice: learn to use your debugger (probably gdb), and try to reproduce the failure under the debugger.不看代码很难说具体什么,所以我给你一些一般性的建议:学会使用你的调试器(可能是gdb),并尝试在调试器下重现故障。 If you're lucky, the segfault will still occur under the debugger, you'll get a stack trace showing where it failed, and that will give you a starting point that will let you work your way back to the true source of the problem.如果你幸运的话,段错误仍然会在调试器下发生,你会得到一个堆栈跟踪,显示它失败的地方,这将为你提供一个起点,让你回到问题的真正根源.

If you're unlucky, the problem might disappear if you compile with debugging support, or run it under gdb.如果你不走运,如果你在调试支持下编译,或者在 gdb 下运行它,问题可能会消失。 In that case you'll have to resort to code inspection, and scrub your code for any undefined behavior (for example, wild or uninitialized pointers, as Billy ONeal suggests).在这种情况下,您将不得不求助于代码检查,并清理您的代码以查找任何未定义的行为(例如,正如 Billy ONeal 所建议的那样,野性或未初始化的指针)。

Set ulimit -c unlimited .设置ulimit -c unlimited

Run your program and let it crash.运行你的程序,让它崩溃。 It should now core dump.它现在应该核心转储。

Run gdb <program-name> core运行gdb <program-name> core

If you use the bt (backtrace) command, it should give you a good idea where the crash is happening.如果您使用bt (backtrace) 命令,它应该可以让您很好地了解崩溃发生的位置。 This should then help you fix it.这应该可以帮助您修复它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM