In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-05-04 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > IT Information >
Share
Shulou(Shulou.com)11/24 Report--
This article comes from the official account of Wechat: developing Internal skills practice (ID:kfngxl). Author: Zhang Yanfei allen
Hello, everyone. I'm Brother Fei!
Stack is the easiest way to use memory in programming. For example, the local variable n in the following simple code allocates memory on the stack.
# include void main () {int n = 0; printf ("0x%x\ n", & n); then I have a few questions to ask you to see if you really know anything about stack memory.
When is the physical memory of the stack allocated?
What is the size limit of the stack? Can this limit be adjusted?
What happens to the application when the stack overflows?
If you do not have a deep understanding of the above problems, Brother Fei will take you to practice the internal skills of the process stack memory today!
First, before the initialization of the process stack, we are in "how does the code you write run?" "this article describes the startup process of the process. When the process starts calling exec to load the executable, it requests an initial memory of 4 KB for the process stack. Today we are going to extract and take a look at this logic.
The loading system calls execve in turn to call do_execve and do_execve_common to complete the actual executable program loading.
/ / file:fs/exec.cstatic int do_execve_common (const char * filename,) {bprm_mm_init (bprm);} will apply for a new address space mm_struct object in bprm_mm_init, ready to be reserved for the new process.
/ / file:fs/exec.cstatic int bprm_mm_init (struct linux_binprm * bprm) {/ / apply for a new address space mm_struct object bprm-mm = mm = mm_alloc (); _ _ bprm_mm_init (bprm);} will also apply for a page of virtual memory space for the stack of the new process as stack memory for the new process. Save the stack pointer to bprm- > p and record it after the application.
/ / file:fs/exec.cstatic int _ bprm_mm_init (struct linux_binprm * bprm) {bprm-vma = vma = kmem_cache_zalloc (vm_area_cachep, GFP_KERNEL); vma-vm_end = STACK_TOP_MAX; vma-vm_start = vma-vm_end-PAGE_SIZE; bprm-p = vma-vm_end-sizeof (void *); what we usually call process virtual address space is represented by vm_area_struct objects in Linux.
Each vm_area_struct (that is, the vma in the _ _ bprm_mm_init function above) represents a range in the process's virtual address space, and its vm_start and vm_end represent the beginning and end of the enabled virtual address range.
/ / file:include/linux/mm_types.hstruct vm_area_struct {unsigned long vm_start; unsigned long vm_end;} note that this is only an address range, not an actual physical memory allocation.
In the _ _ bprm_mm_init function above, a vma kernel object is requested through kmem_cache_zalloc. Vm_end points to STACK_TOP_MAX (near the top of the address space), leaving a Page size between vm_start and vm_end. In other words, the size of the 4KB is prepared for the stack by default. Finally, record the stack pointer to bprm- > p.
The process loading process then uses load_elf_binary to actually start loading executable binaries. When loading, the address space pointer of the previously prepared process stack is set to the new process mm object.
/ / file:fs/binfmt_elf.cstatic int load_elf_binary (struct linux_binprm * bprm) {/ / ELF header parsing / / Program Header reading / / clearing the resources inherited by the parent process retval = flush_old_exec (bprm); current-mm-start_stack = bprm-p;}
In this way, the new process can use the stack to make function calls and apply for local variables in the future.
As we said earlier, this is just an address space object applied to the stack, not physical memory. Let's take a look at when physical memory pages are allocated.
Application for physical pages when the process starts to assign and access variables on the stack while running, a page break will be triggered if the physical page has not been allocated. Interrupts in missing pages to really allocate physical memory.
In order to avoid too much space, the process of triggering a page break is not unfolded. Let's look directly at the core processing entry for page breakers, _ _ do_page_fault, which is located in the arch / x86 / mm / fault.c file.
/ / file:arch/x86/mm/fault.cstatic void _ _ kprobes__do_page_fault (struct pt_regs * regs, unsigned long error_code) {/ / find the corresponding vma vma = find_vmamm according to the new address, address; / / if the starting address of the found vma is smaller than address, then do not call expand_stack, call if likelyvma-vm_start = address goto good_area; if unlikelyexpand_stack (vma, address) bad_arearegs, error_code, address directly Return;} good_area: / / call handle_mm_fault to complete the real memory request fault = handle_mm_fault (mm, vma, address, flags);} when accessing the memory of a variable on the stack, find_vma is first called to find the vma object based on the variable address address. The next call to if (vma- > vm_start vm_end-address)
Calculate the number of pages that need to grow. The calculation formula is grow = (vma- > vm_start-address) > > PAGE_SHIFT
Then it will determine whether the stack space is allowed to be expanded, which is done in acct_stack_growth. If extension is allowed, simply modify vma- > vm_start!
Let's take a look at what restriction judgments have been made by acct_stack_growth.
/ / file:mm/mmap.cstatic int acct_stack_growth (struct vm_area_struct * vma, unsigned long size, unsigned long grow) {/ / check whether the address space exceeds the limit if (! may_expand_vm (mm, grow)) return-ENOMEM; / / check whether it exceeds the stack size limit if (size ACCESS_ONCE [rlimRLIMIT _ STACK] .rlim _ cur) return-ENOMEM; return 0;} only makes a series of judgments in acct_stack_growth. May_expand_vm determines whether the growth of these pages exceeds the limit of the overall virtual address space. What is recorded in rlim [RLIMIT_STACK] .rlim _ cur is the limit of stack space size. These restrictions can be seen through the ulimit command.
The output above # ulimit-amax memory size (kbytes,-m) unlimitedstack size (kbytes,-s) 8192virtual memory (kbytes,-v) unlimited indicates that there is no limit to the size of the virtual address space, and the limit of stack space is 8 MB. If the process stack size exceeds this limit,-ENOMEM is returned. If you feel that the default size of the system is not appropriate, you can modify it through the ulimit command.
# ulimit-s 1024 ulimit-astack size (kbytes,-s) 10240 also has the answer to the second question that begins here. What is the size limit of the stack? Can this limit be adjusted?
The process stack size limit varies from machine to machine and can be viewed or modified using the ulimit command.
As for the opening question 3, what happens to the application when the stack overflows? Write a simple infinite recursive call to know, probably you have also encountered. The result of reporting an error is
Segmentation fault (core dumped) this article summarizes the content of this article, which discusses how process stack memory works.
First, the process applies for a virtual address space vma kernel object to the process stack when it loads. There is a Page between vm_start and vm_end, which means that 4KB space is set aside for the stack by default.
Second, when the process starts assigning and accessing variables on the stack while running, a page break will be triggered if the physical page has not been allocated. The partner system that invokes the kernel in a page fault interrupt actually allocates physical memory.
Third, it automatically expands when the storage in the stack exceeds the 4KB. However, the size is limited, and the size limit can be viewed and set through ulimit-s.
Note that today we are all talking about the process stack. The thread stack is somewhat different from the process stack. We will look at the thread stack separately when we are free later.
At the beginning of the review and summary, we put forward three questions:
Question 1: when is the physical memory of the stack allocated? When a process loads, it simply allocates a range of address space to the stack memory of the new process. The real physical memory is to wait until the access time to trigger a page break, and then apply for it from the partner system.
Question 2: what is the size limit of the stack? Can this limit be adjusted?
The process stack size limit varies from machine to machine and can be viewed or modified using the ulimit command.
Question 3: what happens to the application when the stack overflows? When the stack overflows, we receive an error "Segmentation fault (core dumped)"
Finally, let's think about it together. Why do you think the kernel limits the address space of the process stack?
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.