2
votes

I am getting a segmentation fault in some C code, and I cannot figure out how to read this so I can figure out the problem..

Does anyone have any techniques that can help me? Does anything jump out to you?

Here is gdb output:

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

Here is what gdb backtrace full shows:

(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

Here is dbx output:

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);

Here is the last function call in the stack trace that I can modify (Not in an external library - in create_my_window).. The full code for this class can be seen here: 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);

EDIT

I added a breakpoint in gdb right before the function call, and printed out some values (Not sure if this will help - I am a 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
So what is n_args initialized to?GManNickG
does shell ever get a value other than NULL?Kyle Lutz
sorry, missed GDB part. Can you print backtrace from within GDB? that should give you variables and their values. Look for zeros (null) or some other weird stuff in addresses.Anycorn
Line 180 where you assign a value of win->main_window to the results of a function for creating the main window, even if win itself is/was the main window feels really circular for what it is worth.TheJacobTaylor
I added some gdb output... Is there anything obvious in there?mainstringargs

9 Answers

5
votes

Given that dbx said "Attempting to read 4 bytes through NULL pointer", and that the error was reported on the line with the function call and not inside the XmCreateMainWindow function, I assume the problem has something to do with the statement win->name. This is the only place on this line of C where you would be reading from a pointer before the function is actually called (it will read a copy of the data stored in win->name and pass the copy to the function).

Try inserting the following on the line immediately above the call to XmCreateMainWindow

assert(win != NULL);

You will need to #include <assert.h> if it isn't already. This should verify that win isn't a NULL pointer when the function is called. For the sake of being thorough, you may want to add a similar line for shell as well.

4
votes

Your crash is happening inside libXm. Either your heap has been corrupted beforehand, or you are passing in bad data (or, much less likely, there's a bug in libXm and/or other system libs). The args stuff looks like it is okay (though your memset is a bit non-standard).

To test for heap corruption use Valgrind, but I'm not sure it's available on Solaris. You could build your package on Linux and see if you get the same crash there.

(If you switch to linux you can install the debug symbols + source for libXm easily, to figure out where the data may be going wrong.)

For the 3rd (unlikely) possibility, check you're at the latest patch level.

1
votes

What I can see immediately from looking at your output is that:

a) The version of GDB you are using is outdated by a year.

b) None of the output you provided is very useful; you need to post a backtrace.

Now, the last entry in a backtrace, or rather, where the program actually stopped (libXm in this case), is almost never the actual cause of the problem. Assuming that libXm isn't at fault, you really need a proper backtrace to see the last point of execution which involved the code YOU wrote; this is a more likely source of the problem.

One more thing; learn to use GDB. It's a necessity if you're ever going to write a program longer than a few lines.

1
votes

Your problem is in your memset.

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

Here, you are using &(args) where you should be using args or &args[0]. args is a pointer to the start of the array, and &(args) is a pointer-to-pointer. When you try to memset &(args), you are attempting to write a (potentially) large swath of zeroes over a memory range you shouldn't be writing to. At some point, that command tried to write into a memory range it wasn't supposed to touch, and the system killed it.

1
votes

Replace memset with a function that sets the different args manually. memset should only be used on byte arrays because with any other type 0 may not mean what you think it means.

1
votes

Going through the gdb output can be difficult, so either use an IDE or try to find the bug yourself.

Segmentation Fault is usually caused:

  1. When trying to dereference a NULL pointer
  2. Modifying a string literal, for e.g.
    
      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. Attempting to access already freed/deallocated memory.
  4. Attempting to alter/access memory not allocated to the program.
1
votes

You're passing NULL as the first argument to XmCreateMainWindow(parent, ...) while most samples found on google seem to pass a non-NULL Widget coming from XtVaAppInitialize() there, are you sure that you shouldn't be doing that too?

failing that, in gdb, put a breakpoint on the line 180 win->main_window = XmCreateMainWindow(shell, win->name, args, n_args);

and execute the 'p *win' command there, and the output should be enlightening. Probably a member of the "win" structure that shall be initialized is null or garbage, and that should get you going.

1
votes

This may be a long shot, but have you tried "disassemble" on those memory addresses in the backtrace? If you have some basic understanding of assembly, you might be able to discern something out of place that way. As several people mentioned, you're likely accessing a bad pointer somewhere. Sometimes the assembly will reveal which pointer's address is something that doesn't seem "right." It's something that's pointed me in the right direction in the past.

1
votes

I would drop the memset function calls. All of the examples that I have seen just reset the argument count back to 0.

I am not sure if it is available to you, but DTrace was built for this sort of thing. Here is a blog that talks about it. http://blogs.oracle.com/observatory/entry/d_script_archeology

Jacob