Thread: BSS Segment Size

  1. #1
    Registered User
    Join Date
    Oct 2022
    Posts
    96

    BSS Segment Size

    I'm going through memory layout in C Memory Layout of C Programs - GeeksforGeeksand have been exploring two different programs mention in point 1 and 2 . In both programs, I expected the size of the BSS segment to change based on the content, but I'm consistently getting the same size.

    Could you help me understand why this might be happening? Below are the commands I've tried and their outputs on my Ubuntu system:

    Attached Images Attached Images BSS Segment Size-img_20240501_175038-jpg 

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,127
    First all, please display plain text of the source code and results in CODE tags, NOT fuzzy images! Without seeing your actual code, we cannot comment.

    Why does the 8 byte bss segment bother you? This is a detail for the compiler and the people who write its code!

    Why do you keep asking about obscure details of the language? Why not sit down and actually write some small useful programs?

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,665
    > Could you help me understand why this might be happening?
    Presumably because you never used the global variable, so the compiler just optimised it out.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Apr 2021
    Posts
    142
    You are falling victim to some kind of rounding error. I chased through the article you linked, and followed the steps you are probably following. I got results similar to yours on my system, which is

    Code:
    $ uname -a
    Linux laptop 6.1.0-20-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.85-1 (2024-04-11) x86_64 GNU/Linux
    However, in the interest of SCIENCE!!! I went a little bit further.

    The nm command in unix will print a list of symbols, or "names" (hence, "nm", because 4-5 characters is too many!) found in a binary or object file, along with some other information about them. I got:

    Code:
    $ nm memory-size | grep ' B'  # Show only BSS items
    0000000000004010 B __bss_start
    0000000000004018 B _end
    0000000000004014 B Global
    As you can see, the "Global" (my naming convention is Capitalized_snake_case for global variables) symbol is present, but there is an apparently-deliberate first 32-bit empty area right at the front of the section, and the _end symbol is aligned 8.

    If you remove the global variable and repeat the nm command, the start and end are still at 0 and 8, respectively. So I assume there is either an alignment or a padding rule in effect that the author of the original article did not suffer from.

    To prove this, I changed the Global variable to be an array of 10 integers. At that point, I was surprised to find a bunch of things happening:

    Code:
    $ grep -v '^/' memory-layout.c
    
    #include <stdio.h>
    
    int Global[10];
    
    int main(void)
    {
        return 0;
    }
    
    $ gcc -O0 memory-layout.c -o memory-layout && size memory-layout
       text    data     bss     dec     hex filename
       1216     528      72    1816     718 memory-layout
    
    $ nm memory-layout | grep ' B'
    0000000000004010 B __bss_start
    0000000000004068 B _end
    0000000000004040 B Global
    Notice that the Global symbol has moved to location 0x4040 !!! What does that mean?

    First, there are no other symbols being defined. (Easy to check by NOT filtering only BSS items, and grepping for addresses less than 0x4040, which is trivial using hexadecimal.)

    Next, notice that it's a big, round number. 4040. As soon as you see a "big round" number in hexadecimal, you have to immediately ask yourself: is this alignment-related? I'm assuming that it is. The bottom 2 digits, 0x40, make "64" in decimal terms. I don't know *why* gcc is pushing the alignment up to 64, but it is. (Note: 64 is not the size of anything relevant to C data types. It is the common size of a "cache line." So it may be that gcc is trying to align array data on a cache-line boundary.)

    Finally, note the mathematics: 0x40 is the start of the Global symbol. 0x68 is the _end symbol. 0x68 - 0x40 is 0x28, which is 32+8=40. Since I declared an array of 10 integers, 10 x 4 bytes = 40 = 0x28, so this makes sense.

    Edit:


    I got curious about that first 4-byte skip. So I went back and changed the type of the "global integer" to be a short instead of just int. The output changed like this:

    Code:
    $ nm memory-layout | grep ' B'
    0000000000004010 B __bss_start
    0000000000004018 B _end
    0000000000004012 B Global
    Note that the offset is now at 0x12, instead of 0x14 when it was an int.

    I now suspect that gcc is simply declaring a char as the __bss_start object, and then native alignment rules are causing the initial offset to bump up to whatever the sizeof the global variable is. Still not sure about the 8-byte _end offset, though.
    Last edited by aghast; 1 Weeks Ago at 01:16 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why would they use this segment instead of this one?
    By hannahfox123 in forum C++ Programming
    Replies: 3
    Last Post: 06-21-2010, 08:54 AM
  2. segment notes
    By cs32 in forum C Programming
    Replies: 2
    Last Post: 03-05-2008, 03:30 AM
  3. shmget returning invalid segment size specified
    By BobS0327 in forum Linux Programming
    Replies: 6
    Last Post: 11-08-2006, 06:39 PM
  4. What does this code segment do?
    By Mr. Acclude in forum C++ Programming
    Replies: 2
    Last Post: 09-12-2005, 08:48 PM
  5. segment fault?
    By major_small in forum C++ Programming
    Replies: 4
    Last Post: 09-18-2003, 07:18 PM

Tags for this Thread