argc=Cannot access memory at address 0x0

Hi
I’m a self-trained C programmer getting in trouble finding a segmentation fault error.
Debugging the program all seems coherent except the stack messages (i’m using gdb):


main (argc=Cannot access memory at address 0x0)

to test this I wrote the following program:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void init()
{
    char *ptr;        
   ptr       = (char *) malloc (2);
}
int main (int argc, char *argv])
{
    int i;
    char *progname;
    i=argc;
    progname = argv[0];
    init();
    return 0;
}

whih give me the same error message (find some gdb row explaining the stack error:

Starting program: /home/robber/Linguaggi/fortran/memtest 

Breakpoint 5, main (argc=1, argv=0xbfb1aa84) at memtest.c:17
init () at memtest.c:11

  Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
#1  0x080484fe in main (argc=Cannot access memory at address 0x0
) at memtest.c:19
(gdb) 

How can explain this kind of behaviour? Any hint very appreciated

The program shown does not have any errors. So, if you try it via gdb, it will not give any errors. What are you trying to do?

you’re right but
if you compile it using “electric fence”

gcc -ggdb3 -lefence -o memtest memtest.c

you should get a message of “memory corruption” both from gdb and from electric fence, truly the message doesn’t affect the execution.
I have another program in which I get “Segmentation fault” error and the only corruption that I’m able to detect is the same I’m describing here.

Those line numbers in the error messages don’t match up with the program you posted. Are you sure that’s really the program you compiled?

I deleted some unimportant comments, this should be the coherent output printing the upper stack in gdb

Breakpoint 6, main (argc=1, argv=0xbfd354a4) at memtest.c:15
init () at memtest.c:7

  Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
#1  0x0804850c in main (argc=Cannot access memory at address 0x0
) at memtest.c:16

Your program runs without error here. As a minor point, generally the libraries are put in the order they will be resolved against, so try:

gcc -o memtest memtest.c -ggdb3 -lefence

What do you mean for “here”?
This is the version I used for gdb

GNU gdb 6.8
Copyright (C) 2008 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 "i586-suse-linux"

and gcc


gcc (SUSE Linux) 4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036]
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Don’t you get any message from electric fence and from the debugger?
The memory corruption could give no evidence during the run but increasing the size of the program will show itself in other part of the program.

What I mean is that your program runs fine when compiled either with or without gdb. I did not try it with electric fence. I’m not going to install electric fence just for your program. So there is no error in your program. The error is probably in the way you link for electric fence. What do the instructions for electric fence tell you to do? Did you try putting the libraries at the end of the command line?

Incidentally I specifed -ggdb not -ggdb3 in the command.

Thank you for the answer. I compiled using your command. It is true that the program run fine but my question is if there is memory corruption as it seems from the following code:

GNU gdb 6.8
Copyright (C) 2008 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 "i586-suse-linux"...
Breakpoint 1 at 0x80484ff: file memtest.c, line 15.
(gdb) run
Starting program: /home/robber/Linguaggi/fortran/memtest 

Breakpoint 1, main (argc=1, argv=0xbfb94b44) at memtest.c:15
init () at memtest.c:7

  Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens <bruce@perens.com>
#1  0x08048504 in main (argc=Cannot access memory at address 0x0
) at memtest.c:15
(gdb) p argc
Cannot access memory at address 0x0
(gdb) 

Do you try to run gdb to verify the addresses of the argc variable?

Is it normal that the address of “argc” is changed after the call to init()?

Is my installation of opensuse 11.0 broken?
I am very thankful to anyone would expalin this behaviour or hint for documentation.

Since gdb can access argc just fine, it looks like a limitation of electric fence or just the way it works. Maybe ask an electric fence forum?

I compiled without efence and I don’t think it is normal that gdb can access the correct value of “argc” before the malloc call and cannot access the value of “argc” after. Follow gdb output

Starting program: /home/robber/Linguaggi/fortran/memtest 

Breakpoint 1, main (argc=1, argv=0xbfd204c4) at memtest.c:15
init () at memtest.c:7
#1  0x08048414 in main (argc=1, argv=0xbfd204c4) at memtest.c:15
(gdb) p argc
$1 = 1
#0  init () at memtest.c:8
main (argc=Cannot access memory at address 0x0
) at memtest.c:16
(gdb) p argc
Cannot access memory at address 0x0
(gdb) 

I have no problems of that sort with my gdb. Your output is puzzling. How did your breakpoints get set? I don’t see any input commands by you setting the breakpoints? Do you have some commands in an init file or something? I also don’t see any commands by you to start the program? Is there something you didn’t show?

For your information, I put your source in x.c and did this:

gcc -g -o x x.c
gdb x

Sorry I used the emacs GUI to gdb to put the breakpoints.
One breakpoint is at the init() call line, then I trace the execution for each instruction. You can go inside the init function and go up and down the stack to check the value of argc before and after the malloc call.

Still no problem with my gdb either. But then I’m on a different arch (64-bit) so I can’t reproduce your problem. This is not to say that you don’t have one. Can you try it without the emacs interface?

Incidentally it’s not necessary to cast the return value of malloc with (char *) in the assignment. malloc is prototyped to return void *, which is type compatible with any pointer.

Thank you very much for the help.
Please
would you post your gdb input/output ?
At the moment I cannot have available a 64 bit machine.
I ask to the community if there is any other that can test the program on a 32bit machine to verify if it is a problem relevant to my installation of OS 11.0

$ gdb x
GNU gdb (GDB; openSUSE 11.1) 6.8.50.20081120-cvs
Copyright (C) 2008 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-suse-linux".
For bug reporting instructions, please see:
<http://bugs.opensuse.org/>...
(gdb) b 15
Breakpoint 1 at 0x400574: file x.c, line 15.
(gdb) r
Starting program: /tmp/x

Breakpoint 1, main (argc=1, argv=0x7fffffffdd08) at x.c:15
15          init();
(gdb) s
init () at x.c:7
7          ptr       = malloc (2);
(gdb) where
#0  init () at x.c:7
#1  0x000000000040057e in main (argc=1, argv=0x7fffffffdd08) at x.c:15
(gdb) s
8       }
(gdb) s
main (argc=1, argv=0x7fffffffdd08) at x.c:16
16          return 0;
(gdb) where
#0  main (argc=1, argv=0x7fffffffdd08) at x.c:16
(gdb) quit
The program is running.  Quit anyway (and kill it)? (y or n) y

Just tried it on a 32-bit machine I have access to and something does seem weird with the call frame display after the malloc(). If I replace the malloc() with say “hello” it doesn’t happen. So you may have hit a gdb bug. I suggest you report it on Novell’s bugzilla and they will refer it upstream.

(gdb) s
init () at x.c:7
7          ptr       = malloc (2);
(gdb) where
#0  init () at x.c:7
#1  0x0804845e in main (argc=1, argv=0xbffff694) at x.c:15
(gdb) s
8       }
(gdb) where
#0  init () at x.c:8
#1  0x0804845e in main (argc=0, argv=0x20ff1) at x.c:15
(gdb) s
main (argc=0, argv=0x20ff1) at x.c:16
16          return 0;
(gdb) where
#0  main (argc=0, argv=0x20ff1) at x.c:16
(gdb) q
The program is running.  Quit anyway (and kill it)? (y or n) y

I’ll report the occurence.
I did such test because I got a segmentation fault error in a program in which the corruption appear exactly after the malloc() call after the initialization.

Your reults is one of the variant I got during the debugging of the program.
After the “cannot access the memory at” I got a continuos variations of the addresses and value of argc and argv.
It doesn’t seem only a gdb bug because I got a segmentation fault without using gdb in my program.

Yeah but that could be a bug in your program. gdb bugs are worth more. :slight_smile: