In the K.N.King book, there’s an example:

viewmemory.c
/* Allows the user to view regions of computer memory */

#include <stdio.h>
#include <ctype.h>

typedef unsigned char BYTE;

int main(void)
{
	unsigned int addr;
	int i, n;
	BYTE *ptr;
	
	printf("Address of main function: %x\n", (unsigned int) main);
	printf("Address of addr variable: %x\n", (unsigned int) &addr);
	printf("\nEnter a (hex) address: ");
	scanf("%x", &addr);
	printf("Enter number of bytes to view: ");
	scanf("%d", &n);
	
	printf("\n");
	printf(" Address               Bytes             Characters\n");
	printf(" ------- ------------------------------- ----------\n");
	
	ptr = (BYTE *) addr;
	for (; n > 0; n -= 10) {
		printf("%8X  ", (unsigned int) ptr);
		for (i = 0; i < 10 && i < n; i++)
			printf("%.2X ", *(ptr + i));
		for (; i < 10; i++)
			printf("   ");
		printf(" ");
		for (i = 0; i < 10 && i < n; i++) {
			BYTE ch = *(ptr + i);
			if (!isprint(ch))
				ch = '.';
			printf("%c", ch);
		}
		printf("\n");
		ptr += 10;
	}
	
	return 0;
}

For some reason, when I try to enter addr variable address as the parameter, it has a segmentation fault error. However, in the book’s example and the screenshot from this site in Hangul, there’s no such error?

When I try using gdb to check the issue, here’s what I get:

gdb
$ gdb ./a.out  --silent
Reading symbols from ./a.out...
(gdb) run
Starting program: /home/<username>/Desktop/c-programming-a-modern-approach/low-level-programming/a.out 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/gnu/store/zvlp3n8iwa1svxmwv4q22pv1pb1c9pjq-glibc-2.39/lib/libthread_db.so.1".
Address of main function: 401166
Address of addr variable: ffffd678

Enter a (hex) address: ffffd678
Enter number of bytes to view: 64

 Address               Bytes             Characters
 ------- ------------------------------- ----------

Program received signal SIGSEGV, Segmentation fault.
0x000000000040123a in main () at viewmemory.c:31
warning: Source file is more recent than executable.
31	        printf ("%.2X ", *(ptr + i));
(gdb)

What is going on? By the way, I am using Guix, if that matters in any way. Here’s the output for ldd:

ldd
$ ldd ./a.out 
	linux-vdso.so.1 (0x00007ffecdda9000)
	libgcc_s.so.1 => /gnu/store/w0i4fd8ivrpwz91a0wjwz5l0b2ralj16-gcc-11.4.0-lib/lib/libgcc_s.so.1 (0x00007fcd2627a000)
	libc.so.6 => /gnu/store/zvlp3n8iwa1svxmwv4q22pv1pb1c9pjq-glibc-2.39/lib/libc.so.6 (0x00007fcd2609c000)
  • Treczoks@lemmy.world
    link
    fedilink
    arrow-up
    0
    ·
    18 hours ago

    Depending on the value of ptr and i, you might be accessing data out of your process’ memory space.

    • LalSalaamComrade@lemmy.mlOP
      link
      fedilink
      English
      arrow-up
      0
      ·
      10 hours ago

      But I am trying to read memory assigned by addr variable, which seems to work just fine on the textbook example? (see pic in the link) However, when I try to do the same, I get this:

      $ ./a.out 
      Address of main function: 401166
      Address of addr variable: 3f4c4310
      
      Enter a (hex) address: 3f4c4310
      Enter number of bytes to view: 40
      
       Address               Bytes             Characters
       ------- ------------------------------- ----------
      Segmentation fault
      
      • GissaMittJobb@lemmy.ml
        link
        fedilink
        arrow-up
        0
        ·
        9 hours ago

        The book is from 1996, and there’s a decent chance that the screenshot was made on an older OS that does not have the same memory protection features as a modern OS would have.

        Try a few of the following and see if they segfault:

        • Read only as much memory as the size of the pointer addr
        • Offset the value of addr by -64 and read 64 from there
        • Do the same but with smaller values
        • LalSalaamComrade@lemmy.mlOP
          link
          fedilink
          English
          arrow-up
          0
          ·
          8 hours ago

          The pointer addr is actually undefined, and currently points to some random every time it is executed. Could this be where the memory protection is being triggered, preventing access to other segments?

          • GissaMittJobb@lemmy.ml
            link
            fedilink
            arrow-up
            0
            ·
            8 hours ago

            Could be, yeah.

            I guess I didn’t read the code well enough, but I was expecting addr to point to somewhere on the stack.

            I guess that’s something to try - declare and assign a variable and then print the address of it, and then use that to take a look at stack memory.