故障排除故障

时间:2010-02-19 04:45:42

标签: c++ c gdb segmentation-fault x11

我在一些C代码中遇到了分段错误,我无法弄清楚如何阅读这个以便我可以找出问题..

有没有人有任何可以帮助我的技巧?有什么事情可以跳到你身边吗?

这是gdb输出:

GNU gdb 6.8 for GNAT Pro 6.2.1 (20090115) [rev:143235]
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
See your support agreement for details of warranty and support.
If you do not have a current support agreement, then there is absolutely
no warranty for this version of GDB.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "sparc-sun-solaris2.8"...
Reading symbols from /usr/lib/libsocket.so.1...done.
Loaded symbols for /usr/lib/libsocket.so.1
Reading symbols from /usr/lib/libnsl.so.1...done.
Loaded symbols for /usr/lib/libnsl.so.1
Reading symbols from /usr/lib/libgen.so.1...done.
Loaded symbols for /usr/lib/libgen.so.1
Reading symbols from /usr/lib/libintl.so.1...
warning: Lowest section in /usr/lib/libintl.so.1 is .dynamic at 00000074
done.
Loaded symbols for /usr/lib/libintl.so.1
Reading symbols from /usr/lib/libw.so.1...
warning: Lowest section in /usr/lib/libw.so.1 is .dynamic at 00000074
done.
Loaded symbols for /usr/lib/libw.so.1
Reading symbols from /usr/lib/libm.so.1...done.
Loaded symbols for /usr/lib/libm.so.1
Reading symbols from /opt/services/AZJCommonZJX/solaris/lib/libazjcommonjcxC.so...done.
Loaded symbols for /opt/services/AZJCommonZJX/solaris/lib/libazjcommonjcxC.so
Reading symbols from /usr/openwin/lib/libXext.so.0...done.
Loaded symbols for /usr/openwin/lib/libXext.so.0
Reading symbols from /usr/openwin/lib/libX11.so.4...done.
Loaded symbols for /usr/openwin/lib/libX11.so.4
Reading symbols from /usr/openwin/lib/libXmu.so.4...done.
Loaded symbols for /usr/openwin/lib/libXmu.so.4
Reading symbols from /usr/openwin/lib/libXt.so.4...done.
Loaded symbols for /usr/openwin/lib/libXt.so.4
Reading symbols from /usr/dt/lib/libXm.so.3...done.
Loaded symbols for /usr/dt/lib/libXm.so.3
Reading symbols from /usr/lib/libc.so.1...done.
Loaded symbols for /usr/lib/libc.so.1
Reading symbols from /opt/services/AZJCommonWork/solaris/lib/libazjcommonwork.so...done.
Loaded symbols for /opt/services/AZJCommonWork/solaris/lib/libazjcommonwork.so
Reading symbols from /opt/services/AZJCommonWork/solaris/lib/libazjcommonworkC.so...done.
Loaded symbols for /opt/services/AZJCommonWork/solaris/lib/libazjcommonworkC.so
Reading symbols from /app/gnatpro6.2.1/lib/gcc/sparc-sun-solaris2.8/4.3.3/rts-native/adalib/libgnarl-6.2.so...done.
Loaded symbols for /opt/tools/SunOS/gnatpro6.2.1/lib/gcc/sparc-sun-solaris2.8/4.3.3/adalib/libgnarl-6.2.so
Reading symbols from /app/gnatpro6.2.1/lib/gcc/sparc-sun-solaris2.8/4.3.3/rts-native/adalib/libgnat-6.2.so...done.
Loaded symbols for /opt/tools/SunOS/gnatpro6.2.1/lib/gcc/sparc-sun-solaris2.8/4.3.3/adalib/libgnat-6.2.so
Reading symbols from /usr/lib/libpthread.so.1...
warning: Lowest section in /usr/lib/libpthread.so.1 is .dynamic at 00000074
done.
Loaded symbols for /usr/lib/libpthread.so.1
Reading symbols from /usr/lib/librt.so.1...done.
Loaded symbols for /usr/lib/librt.so.1
Reading symbols from /app/gnatpro6.2.1/lib/libstdc++.so.6...done.
Loaded symbols for /opt/tools/SunOS/gnatpro6.2.1/lib/libstdc++.so.6
Reading symbols from /app/gnatpro6.2.1/lib/libgcc_s.so.1...done.
Loaded symbols for /opt/tools/SunOS/gnatpro6.2.1/lib/libgcc_s.so.1
Reading symbols from /usr/lib/libthread.so.1...
warning: Lowest section in /usr/lib/libthread.so.1 is .dynamic at 00000074
done.
Loaded symbols for /usr/lib/libthread.so.1
Reading symbols from /usr/lib/libaio.so.1...done.
Loaded symbols for /usr/lib/libaio.so.1
Reading symbols from /usr/lib/libmd.so.1...done.
Loaded symbols for /usr/lib/libmd.so.1
Reading symbols from /usr/lib/libm.so.2...done.
Loaded symbols for /usr/lib/libm.so.2
Reading symbols from /platform/sun4v/lib/libc_psr.so.1...done.
Loaded symbols for /platform/SUNW,Sun-Fire-T200/lib/libc_psr.so.1
Reading symbols from /lib/ld.so.1...done.
Loaded symbols for /lib/ld.so.1
Core was generated by `./solaris/apsui -aps_instance 1006 -aps_ato 0 -reject_menu_tearoff -aps_ipc_'.
Program terminated with signal 11, Segmentation fault.
[New process 75224    ]
#0  0x7f1e4d00 in _XmGetFocusData () from /usr/dt/lib/libXm.so.3

以下是gdb backtrace full的内容:

(gdb) bt full
#0  0x7f1e4d00 in _XmGetFocusData () from /usr/dt/lib/libXm.so.3
No symbol table info available.
#1  0x7f1e2768 in _XmNavigInitialize () from /usr/dt/lib/libXm.so.3
No symbol table info available.
#2  0x7f1e8adc in Initialize () from /usr/dt/lib/libXm.so.3
No symbol table info available.
#3  0x7f357760 in CallInitialize () from /usr/openwin/lib/libXt.so.4
No symbol table info available.
#4  0x7f3576b4 in CallInitialize () from /usr/openwin/lib/libXt.so.4
No symbol table info available.
#5  0x7f3576b4 in CallInitialize () from /usr/openwin/lib/libXt.so.4
No symbol table info available.
#6  0x7f353804 in xtCreate () from /usr/openwin/lib/libXt.so.4
No symbol table info available.
#7  0x7f35bf0c in _XtCreateWidget () from /usr/openwin/lib/libXt.so.4
No symbol table info available.
#8  0x7f35bc8c in XtCreateWidget () from /usr/openwin/lib/libXt.so.4
No symbol table info available.
#9  0x7f6026f8 in create_my_window (win=0xd3bc0)
    at /opt/services/AZJCommonZJX/src/uim/create/create_my_window.c:180
    n_args = 0
    args = {{name = 0x0, value = 0} }
    err_msg = '\0' , "ÿ¿Ïä", '\0' , "main_window_menu\000T_CMD MARITIME_TGT_CMD TEST \000K1\177}al\000\000\000\004\000\000\000\001\000\000\000\000"...
    shell = (Widget) 0xd50b8
    object_width = 0
    object_height = 1660944384
    window_name = "TBM_PrimaryWin\000ä\000\000\000\000\177ÿÿø\177ÿü\000\177\023\222¤\000\000 \000\000\f\215ð\000\f\217 \177\023\222¬\177ÿü\000\000\000\000\000ÿ¿Î\200\177\005f,\000\000\000\000\177\023Vx\000\fO \000\aÀ\020\000\fO \1772*\000ui_ipc_xref."
    icon_pixmap = 8332422
    obj = (gen_obj_list_t *) 0x6b0
    vis = (vis_list_t *) 0x7f832bb8
    toolbar = (toolbar_t *) 0x0
#10 0x7f5f524c in create_my_window (in_buff=0x19750 "main_window_menu")
    at /opt/services/AZJCommonZJX/src/uim/create/create_my_window.c:431
    func_name = "create_my_window"
    str = "\000\000\000\000\000\000\000\000¿¿Ä6'yC \000\000\000\000\000\000\000\000\177\235p0\000\000\000\000\000\003eÈ\000\003e¸\000\000\000\004ÿÿ\000\000\000\000\000\000ÿÿÿß\000\000\000\017\000\000\000\017\000\003^\200ÿ¿Ô\000\000\000\000\000\000\000\000\001\000\000\000\004\000\000\000\017ÿ¿Ó \177\2133, "\001\000\000\000\234\000\000\000\000\000\000\000\036\000\000\000\000\000\rP\000ÿ¿Ô \177\213\022\020\000"...
    ptr = 0x19760 ""
    keyword = 0x8a130 ""
    window_name = 0x8a130 ""
---Type  to continue, or q  to quit---
    title_name = "\000¿ÒØ\177\211îÄ\000\000\000\000\000\000\000\004", '\0' , "\003e¸\000\000\000\004ÿÿ\000\000\000\000\000\000ÿÿÿß\000\000\000\017\000\000\000 \000\001\023T\177¿sÈ\177·\fà\005øص\000\000\000@\177·\020Xÿ¿Ó8"
    full_title_name = 0x2b870 "TAP"
    object_width = 2141025804
    object_height = 1
    window_width = 0
    window_height = 0
    first_object = 1
    other_obj = 0
    centered_max_width = 18866798

这是dbx输出:

For information about new features see `help changes'
To remove this message, put `dbxenv suppress_startup_message 7.7' in your .dbxrc
Reading apsui
core file header read successfully
Reading ld.so.1
Reading libsocket.so.1
Reading libnsl.so.1
Reading libgen.so.1
Reading libintl.so.1
Reading libw.so.1
Reading libm.so.1
Reading librt.so.1
Reading libazjcommonjcxC.so
Reading libXext.so.0
Reading libX11.so.4
Reading libXmu.so.4
Reading libXt.so.4
Reading libXm.so.3
Reading libazjcommonwork.so
Reading libazjcommonworkC.so
Reading libgnarl-6.2.so
Reading libgnat-6.2.so
Reading libpthread.so.1
Reading libc.so.1
Reading libaio.so.1
Reading libmd.so.1
Reading libstdc++.so.6.0.10
Reading libgcc_s.so.1
Reading libthread.so.1
Reading libm.so.2
Reading libc_psr.so.1
t@1 (l@1) program terminated by signal SEGV (no mapping at the fault address)
0x7f264d00: _XmGetFocusData+0x0098: ld       [%o0], %o1
Current function is create_my_window
  180     win->main_window = MyWindow(shell, win->name, args, n_args);
>check -all
access checking - ON
memuse checking - ON
Running: apsui 
(process id 18052)
Reading rtcapihook.so
Reading libdl.so.1
Reading rtcaudit.so
Reading libmapmalloc.so.1
Reading rtcboot.so
Reading librtc.so
RTC: Enabling Error Checking...
RTC: Using UltraSparc trap mechanism
RTC: See `help rtc showmap' and `help rtc limitations' for details.
RTC: Running program...
azjcommonworkdummy.adb elaborated
 User Interface version TOOLKIT : 22 MAR 2010 UIMPID=18052
Read from unallocated (rua) on thread 1:
Attempting to read 4 bytes through NULL pointer
t@1 (l@1) stopped in _XmGetFocusData at 0x5d164d00
0x5d164d00: _XmGetFocusData+0x0098: ld       [%o0], %o1
Current function is create_my_window
  180     win->main_window = MyWindow(shell, win->name, args, n_args);

这是我可以修改的堆栈跟踪中的最后一个函数调用(不在外部库中 - 在create_my_window中)..这个类的完整代码可以在这里看到:http://utilitybase.com/paste/26607

void create_my_window( window_t *win)
{
  Cardinal n_args;
  Arg      args[MAX_ARGS];

  Widget   shell = NULL;

//MORE STUFF HERE

  memset(&(args), 0, sizeof(Arg)*MAX_ARGS); n_args = 0;
  if (win->attributes != PRIMARY_WINDOW) {
    XtSetArg(args[n_args], XmNtopAttachment, XmATTACH_FORM); n_args++;
    XtSetArg(args[n_args], XmNbottomAttachment, XmATTACH_FORM); n_args++;
    XtSetArg(args[n_args], XmNleftAttachment, XmATTACH_FORM); n_args++;
    XtSetArg(args[n_args], XmNrightAttachment, XmATTACH_FORM); n_args++;
    XtSetArg(args[n_args], XmNtopOffset, 0); n_args++;
    XtSetArg(args[n_args], XmNbottomOffset, 0); n_args++;
    XtSetArg(args[n_args], XmNleftOffset, 0); n_args++;
    XtSetArg(args[n_args], XmNrightOffset, 0); n_args++;
  }
  win->main_window = XmCreateMainWindow(shell, win->name, args, n_args);

修改

我在函数调用之前在gdb中添加了一个断点,并打印出一些值(不确定这是否有用 - 我是n00b):

Breakpoint 1, create_my_window (win=0x9b378)
    at /opt/services/AZJCommonZJX/src/jzs/create/create_my_window.c:179
179   printf("%d",n_args);
(gdb) p *win
$1 = {struct_type = 1045, next = 0x0, hash_name = 971, 
  name = 0x994e8 "error_log", widget = 0x0, main_window = 0x0, workarea = 0x0, 
  menu_bar = 0x0, message_window = 0x0, window_RC = 0x0, working_box = 0, 
  working_identifier = 0x0, has_message_area = 0, pos = {x = 0, y = 0}, 
  illegal_char_set = 0x0, height = 0, width = 0, configured = 0, 
  actions = 0x0, title = 0x99d18, help_text = 0x0, groups = 0x0, 
  scroll_bars = 0x0, write_protect = 0, attributes = 0, initial_focus = {
    obj_type = 0, obj_name = 0x0, area = 0x0}, text_edit = {
    text_selected_widget = 0x0, text_focus_widget = 0x0, updated_widget = 0x0, 
    start = 0, end = 0, updated_text = 0x0, last_operation = 0}, 
  close_rqt = 0x0, kill_application_action_list_name = 0x0, parent = 0x0, 
  gen_objs = 0x99da0, panes = 0x0, table_list = 0x0, selected_table = 0x0, 
  dialogs = 0x0, has_been_loaded = 0 '\0', source_file_name = 0x0}
(gdb) p *shell
$2 = {core = {self = 0x9db50, widget_class = 0xfec7897c, parent = 0x0, 
    xrm_name = 466, being_destroyed = 0 '\0', destroy_callbacks = 0x9ae58, 
    constraints = 0x0, x = 0, y = 0, width = 0, height = 0, border_width = 1, 
    managed = 0 '\0', sensitive = 1 '\001', ancestor_sensitive = 1 '\001', 
    event_table = 0x9ad98, tm = {translations = 0x0, proc_table = 0x0, 
      current_state = 0x0, lastEventTime = 0}, accelerators = 0x0, 
    border_pixel = 0, border_pixmap = 2, popup_list = 0x0, num_popups = 0, 
    name = 0x7776e "TBM_Dialog_Fixed", screen = 0x7a7e0, colormap = 32, 
    window = 0, depth = 24, background_pixel = 12825262, 
    background_pixmap = 2, visible = 1 '\001', mapped_when_managed = 1 '\001'}}
(gdb) p *args
$3 = {name = 0x0, value = 0}
(gdb) p *n_args
Cannot access memory at address 0x0
(gdb) p n_args
$4 = 0
(gdb) p args
$5 = {{name = 0x0, value = 0} <repeats 20 times>}

9 个答案:

答案 0 :(得分:5)

鉴于dbx说“尝试通过NULL指针读取4个字节”,并且错误是在函数调用的行上报告而不是在XmCreateMainWindow函数内,我认为问题有关声明win->name。这是C行的唯一位置,在实际调用函数之前,您将从指针读取它(它将读取存储在win->name中的数据的副本并将副本传递给函数)。 / p>

尝试在调用XmCreateMainWindow

上方的行上插入以下内容
assert(win != NULL);

如果尚未#include <assert.h>,则需要win。这应该在调用函数时验证shell不是NULL指针。为了彻底,您可能还想为{{1}}添加类似的行。

答案 1 :(得分:4)

您的崩溃发生在libXm中。您的堆预先已损坏,或者您传递了错误的数据(或者,更不可能的是,libXm和/或其他系统库中存在错误)。 args的东西看起来没问题(虽然你的memset有点不标准)。

要测试堆损坏使用Valgrind ,但我不确定它是否在Solaris上可用。你可以在Linux上构建你的软件包,看看你是否遇到了同样的崩溃。

(如果你切换到linux,你可以轻松地安装libXm的调试符号+源码,找出数据可能出错的地方。)

对于第3种(不太可能)的可能性,请检查您是否处于最新补丁级别。

答案 2 :(得分:1)

通过查看输出,我可以立即看到:

a)您使用的GDB版本已过期一年。

b)您提供的输出都不是非常有用;你需要发布一个回溯。

现在,回溯中的最后一个条目,或者更确切地说,程序实际停止的位置(在本例中为libXm)几乎不是问题的实际原因。假设libXm没有错,你真的需要一个适当的回溯来查看涉及你编写的代码的最后一个执行点;这是问题的一个更可能的来源。

还有一件事;学会使用GDB。如果你要编写的程序超过几行,这是必要的。

答案 3 :(得分:1)

你的问题出在你的记忆中。

Arg      args[MAX_ARGS];
...
memset(&(args), 0, sizeof(Arg)*MAX_ARGS); n_args = 0;

在这里,您使用的是&(args),您应该使用args&args[0]args是指向数组开头的指针,&(args)是指向指针的指针。当您尝试memset &(args)时,您试图在不应该写入的内存范围内写入(可能)大的零行。在某些时候,该命令试图写入一个它不应该触及的内存范围,并且系统将其杀死。

答案 4 :(得分:1)

使用手动设置不同参数的函数替换memset。 memset应仅用于字节数组,因为任何其他类型0可能并不意味着您的意思。

答案 5 :(得分:1)

通过gdb输出可能很困难,所以要么使用IDE,要么尝试自己找到bug。

通常会导致分段错误:

  1. 尝试取消引用NULL指针时
  2. 修改字符串文字,例如

    
      char *s = "string";
      *(s+1) = 's';
    
    
      Correct way would be to allocate memory to the pointer or use Character Array or use:
    
      char *s = strdup("string");
      *(s+1) = 's';
    
    

  3. 正在尝试访问已释放/已释放的内存。
  4. 尝试更改/访问未分配给程序的内存。

答案 6 :(得分:1)

你将NULL作为XmCreateMainWindow(parent, ...)的第一个参数传递,而谷歌上发现的大多数样本似乎都传递了来自XtVaAppInitialize()的非NULL Widget,你确定你应该'那也是这样吗?

失败,在gdb中,在第180行放置一个断点 win->main_window = XmCreateMainWindow(shell, win->name, args, n_args);

并在那里执行'p * win'命令,输出应该很有启发性。可能被初始化的“胜利”结构的成员可能是空的或垃圾,这应该让你去。

答案 7 :(得分:1)

我会删除memset函数调用。我看到的所有示例都将参数计数重置为0。

我不确定您是否可以使用它,但DTrace是为此类内容而构建的。这是一个讨论它的博客。 http://blogs.oracle.com/observatory/entry/d_script_archeology

雅各

答案 8 :(得分:1)

这可能是一个很长的镜头,但您是否尝试在反向跟踪中对这些内存地址进行“反汇编”?如果您对装配有一些基本的了解,那么您可能能够以这种方式辨别出某些不合适的东西。有几个人提到过,你可能会在某个地方访问一个坏指针。有时程序集会显示哪个指针的地址看起来是“正确的”。这是过去我指向正确方向的东西。