導航:首頁 > 編程系統 > linux內核空間堆棧

linux內核空間堆棧

發布時間:2023-05-18 11:10:50

linux為什麼需要內核棧,系統調用時直接使用用戶棧不行嗎

內核棧和用戶棧區別:
intel的cpu分為四個運行級別ring0~ring3
內核創建進程,創建進程的同時創建進程式控制制塊,創建進程自己的堆棧
一個進程有兩個堆棧,用戶棧和系統棧
用戶堆棧的空間指向用戶地址空間,內核堆棧的空間指向內核地址空間。
有個CPU堆棧指針寄存器,進程運行的狀態有用戶態和內核態,當進程運行在用戶態時。CPU堆棧指針寄存器指向的是用戶堆棧地址,使用的是用戶堆棧;當進程運行在內核態時,CPU堆棧指針寄存器指向的是內核堆棧地址,使用的是內核堆棧。
堆棧切換
當系統因為系統調用(軟中斷)或硬體中斷,CPU切換到特權工作模式,進程陷入內核態,進程使用的棧也要從用戶棧轉向系統棧。
從用戶態到內核態要兩步驟,首先是將用戶堆棧地址保存到內核堆棧中,然後將CPU堆棧指針寄存器指向內核堆棧。
當由內核態轉向用戶態,步驟首先是將內核堆棧中得用戶堆棧地址恢復到CPU堆棧指針寄存器中。
內核棧和用戶棧區別
1.
棧是系統運行在內核態的時候使用的棧,用戶棧是系統運行在用戶態時候使用的棧。
當進程由於中斷進入內核態時,系統會把一些用戶態的數據信息保存到內核棧中,當返回到用戶態時,取出內核棧中得信息恢復出來,返回到程序原來執行的地方。
用戶棧就是進程在用戶空間時創建的棧,比如一般的函數調用,將會用到用戶棧。
2.
內核棧是屬於操作系統空間的一塊固定區域,可以用於保存中斷現場、保存操作系統子程序間相互調用的參數、返回值等。
用戶棧是屬於用戶進程空間的一塊區域,用戶保存用戶進程子程序間的相互調用的參數、返回值等。
3.
每個Windows 都有4g的進程空間,系統棧使用進程空間的地段部分,用戶棧是高端部分如果用戶要直接訪問系統棧部分,需要有特殊的方式。
為何要設置兩個不同的棧?
共享原因:
內核的代碼和數據是為所有的進程共享的,如果不為每一個進程設置對應的內核棧,那麼就不能實現不同的進程執行不同的代碼。
安全原因:
如果只有一個棧,那麼用戶就可以修改棧內容來突破內核安全保護。

Ⅱ Linux內核——用戶堆棧和內核堆棧

每個進程都有用戶堆棧和內核堆棧兩個堆棧。進程在用戶態時使用用戶堆棧,陷入到內核態時便使用內核堆棧。

Ⅲ linux 線程間共享內核棧嗎

首先,我們知道所有線程共享主線程的虛擬地址空間(current->mm指向同一個地址),且都有自己的用戶態堆棧(共享父進程的地址空間,再在裡面分配自己的獨立棧,默認2M)。這是毫無疑問的,但還有一點我沒搞明白,內核棧是共享還是獨立的?猜測:獨立的。理由:要不然內核棧對應的thread_info中的tast_struct沒有辦法與每個線程對應起來,因為現在已經有多個task_struct了,但保存內核棧的thread_info(其實是thread_union聯合體)中只能保存一個task_struct。所以理論上分析,雖然可以共享地址空間,但每個線程還是需要一個單獨的內核棧的。看代碼:分析創建線程最終肯定會走到內核函數do_fork()中來的,所以從此函數看起。do_fork()->_process()->p_task_struct()fork.c中p_task_struct()的實現:static struct task_struct *p_task_struct(struct task_struct *orig){struct task_struct *tsk;struct thread_info *ti;unsigned long *stackend;int node = tsk_fork_get_node(orig);int err;tsk = alloc_task_struct_node(node);if (!tsk)return NULL;ti = alloc_thread_info_node(tsk, node);/*就是這里,果然分配內核棧了*/if (!ti)goto free_tsk;err = arch_p_task_struct(tsk, orig);/*這里分配task_struct結構*/if (err)goto free_ti;tsk->stack = ti; ...}

Ⅳ linux 設置堆棧大小 為無限制

在來/etc/profile 的最後面添加ulimit -s unlimited 保存源,source /etc/profile使修改文件生效

linux查看修改線程默認棧空間大小 :ulimit -s
1、通過命令 ulimit -s 查看linux的默認棧空間大小,默認情況下 為10240 即10M
2、通過命令 ulimit -s 設置大小值 臨時改變棧空間大小:ulimit -s 102400, 即修改為100M
3、可以在/etc/rc.local 內 加入 ulimit -s 102400 則可以開機就設置棧空間大小
4、在/etc/security/limits.conf 中也可以改變棧空間大小:
#<domain> <type> <item> <value>
* soft stack 102400
重新登錄,執行ulimit -s 即可看到改為102400 即100M

Ⅳ 怎麼解決 LINUX 堆棧溢出內存的問題

【緩沖區溢出的處理】
你屋子裡的門和窗戶越少,入侵者進入的方式就越少……
由於緩沖區溢出是一個編程問題,所以只能通過修復被破壞的程序的代碼而解決問題。如果你沒有源代碼,從上面「堆棧溢出攻擊」的原理可以看出,要防止此類攻擊,我們可以:
① 開放程序時仔細檢查溢出情況,不允許數據溢出緩沖區。由於編程和編程語言的原因,這非常困難,而且不適合大量已經在使用的程序;
② 使用檢查堆棧溢出的編譯器或者在程序中加入某些記號,以便程序運行時確認禁止黑客有意造成的溢出。問題是無法針對已有程序,對新程序來講,需要修改編譯器;
③ 經常檢查你的操作系統和應用程序提供商的站點,一旦發現他們提供的補丁程序,就馬上下載並且應用在系統上,這是最好的方法。但是系統管理員總要比攻擊者慢 一步,如果這個有問題的軟體是可選的,甚至是臨時的,把它從你的系統中刪除。舉另外一個例 子,你屋子裡的門和窗戶越少,入侵者進入的方式就越少。
----------------------------------------------------------------------------------------------------------------------------------------
char buf[3];
memset(buf,0x55,10);
這個程序就存在溢出

對數據塊的訪問超出該數據塊的地址范圍
===================================================================================
【一個檢測工具
Valgrind 是一款 Linux下(支持 x86、x86_64和ppc32)程序的內存調試工具,它可以對編譯後的二進製程序進行內存使用監測(C語言中的 malloc 和 free,以及 C++ 中的 new 和 delete),找出內存泄漏問題。

Valgrind 中包含的 Memcheck 工具可以檢查以下的程序錯誤:

使用未初始化的內存 (Use of uninitialised memory)
使用已經釋放了的內存 (Reading/writing memory after it has been free』d)
使用超過 malloc 分配的內存空間(Reading/writing off the end of malloc』d blocks)
對堆棧的非法訪問(Reading/writing inappropriate areas on the stack)
申請的空間是否有釋放(Memory leaks – where pointers to malloc』d blocks are lost forever)
malloc/free/new/delete 申請和釋放內存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])
src 和 dst 的重疊(Overlapping src and dst pointers in memcpy() and related functions)
重復 free

① 編譯安裝 Valgrind:
# wget http://valgrind.org/downloads/valgrind-3.4.1.tar.bz2
# tar xvf valgrind-3.4.1.tar.bz2
# cd valgrind-3.4.1/
# ./configure
…………
Primary build target: X86_LINUX
Secondary build target:
Default supp files: exp-ptrcheck.supp xfree-3.supp xfree-4.supp glibc-2.X-drd.supp glibc-2.34567-NPTL-helgrind.supp glibc-2.5.supp
# make
# make install
# whereis valgrind
valgrind:
/usr/bin/valgrind
/usr/lib/valgrind
/usr/local/bin/valgrind
/usr/local/lib/valgrind
/usr/include/valgrind
/usr/share/man/man1/valgrind.1.gz
運行程序
使用示例:對「ls」程序進程檢查,返回結果中的「definitely lost: 0 bytes in 0 blocks.」表示沒有內存泄漏。
# /usr/local/bin/valgrind --tool=memcheck --leak-check=full ls /
==29801== Memcheck, a memory error detector.
==29801== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==29801== Using LibVEX rev 1884, a library for dynamic binary translation.
==29801== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==29801== Using valgrind-3.4.1, a dynamic binary instrumentation framework.
==29801== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==29801== For more details, rerun with: -v
==29801==
bin etc lost+found mnt proc selinux sys usr
boot home media net root smokeping tftpboot var
dev lib misc opt sbin srv tmp
==29801==
==29801== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 21 from 1)
==29801== malloc/free: in use at exit: 14,744 bytes in 32 blocks.
==29801== malloc/free: 162 allocs, 130 frees, 33,758 bytes allocated.
==29801== For counts of detected errors, rerun with: -v
==29801== searching for pointers to 32 not-freed blocks.
==29801== checked 139,012 bytes.
==29801==
==29801== LEAK SUMMARY:
==29801== definitely lost: 0 bytes in 0 blocks.
==29801== possibly lost: 0 bytes in 0 blocks.
==29801== still reachable: 14,744 bytes in 32 blocks.
==29801== suppressed: 0 bytes in 0 blocks.
==29801== Reachable blocks (those to which a pointer was found) are not shown.
==29801== To see them, rerun with: --leak-check=full --show-reachable=yes
----------------------------------------------------------------------------------------------------------------------------------------
# /usr/local/bin/valgrind --tool=memcheck --leak-check=full ps /
==29898== Memcheck, a memory error detector.
==29898== Copyright (C) 2002-2008, and GNU GPL'd, by Julian Seward et al.
==29898== Using LibVEX rev 1884, a library for dynamic binary translation.
==29898== Copyright (C) 2004-2008, and GNU GPL'd, by OpenWorks LLP.
==29898== Using valgrind-3.4.1, a dynamic binary instrumentation framework.
==29898== Copyright (C) 2000-2008, and GNU GPL'd, by Julian Seward et al.
==29898== For more details, rerun with: -v
==29898==
ERROR: Garbage option.
********* simple selection ********* ********* selection by list *********
-A all processes -C by command name
-N negate selection -G by real group ID (supports names)
-a all w/ tty except session leaders -U by real user ID (supports names)
-d all except session leaders -g by session OR by effective group name
-e all processes -p by process ID
T all processes on this terminal -s processes in the sessions given
a all w/ tty, including other users -t by tty
g OBSOLETE -- DO NOT USE -u by effective user ID (supports names)
r only running processes U processes for specified users
x processes w/o controlling ttys t by tty
*********** output format ********** *********** long options ***********
-o,o user-defined -f full --Group --User --pid --cols --ppid
-j,j job control s signal --group --user --sid --rows --info
-O,O preloaded -o v virtual memory --cumulative --format --deselect
-l,l long u user-oriented --sort --tty --forest --version
-F extra full X registers --heading --no-heading --context
********* misc options *********
-V,V show version L list format codes f ASCII art forest
-m,m,-L,-T,H threads S children in sum -y change -l format
-M,Z security data c true command name -c scheling class
-w,w wide output n numeric WCHAN,UID -H process hierarchy
==29898==
==29898== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 14 from 1)
==29898== malloc/free: in use at exit: 16 bytes in 2 blocks.
==29898== malloc/free: 20 allocs, 18 frees, 2,344 bytes allocated.
==29898== For counts of detected errors, rerun with: -v
==29898== searching for pointers to 2 not-freed blocks.
==29898== checked 263,972 bytes.
==29898==
==29898== 8 bytes in 1 blocks are definitely lost in loss record 2 of 2
==29898== at 0x4005A88: malloc (vg_replace_malloc.c:207)
==29898== by 0xBFF6DF: strp (in /lib/libc-2.5.so)
==29898== by 0x804A464: (within /bin/ps)
==29898== by 0x804A802: (within /bin/ps)
==29898== by 0x804964D: (within /bin/ps)
==29898== by 0xBA5E8B: (below main) (in /lib/libc-2.5.so)
==29898==
==29898== LEAK SUMMARY:
==29898== definitely lost: 8 bytes in 1 blocks.
==29898== possibly lost: 0 bytes in 0 blocks.
==29898== still reachable: 8 bytes in 1 blocks.
==29898== suppressed: 0 bytes in 0 blocks.
==29898== Reachable blocks (those to which a pointer was found) are not shown.
==29898== To see them, rerun with: --leak-check=full --show-reachable=yes

Ⅵ linux系統最大堆棧內存

linux系統最大堆棧消搜內存是-Xmx512m。根據查找相關公開資料顯敏簡示,linux系統堆棧大小拿拿歷的配置啟動參數,初始堆大小-Xms32m最大堆大小-Xmx512m。

Ⅶ linux內核中內核局部變數過大不會導致棧溢出嗎

不會首先全局變數是不佔堆棧空間的
全局全量編譯的時侯是放在.data段的
只有沒有static修飾的局部變數在程序運行的時侯臨時分配在棧上,new,或malloc等定義的變數分配在堆上
如果想讓棧溢出也很容易,棧也有其極限的,只要定義一個無限遞歸函數,讓它沒完沒了的遞歸就行了,一會就崩了。
建議學一下編譯原理

Ⅷ 求教關於linux的堆棧設置

在/etc/profile 的最後面添加ulimit -s unlimited 保存,source /etc/profile使修改文件生效

linux查看修改線程默認棧空間大小 :ulimit -s
1、通過命令 ulimit -s 查看linux的默認棧空間大小,默認情況下 為10240 即10M
2、通過命令 ulimit -s 設置大小值 臨時改變棧空間大小:ulimit -s 102400, 即修改為100M
3、可以在/etc/rc.local 內 加入 ulimit -s 102400 則可以開機就設置棧空間大小
4、在/etc/security/limits.conf 中也可以改變棧空間大小:
#<domain> <type> <item> <value>
* soft stack 102400
重新登錄,執行ulimit -s 即可看到改為102400 即100M

Ⅸ Linux內核中用戶空間棧和內核棧的區別

您好,很高興為您解答。

1.進程的堆棧

內核在創建進程的時候,在創建task_struct的同事,會為進程創建相應的堆棧。每個進程會有兩個棧,一個用戶棧,存在於用戶空間,一個內核棧,存在於內核空間。當進程在用戶空間運行時,cpu堆棧指針寄存器裡面的內容是用戶堆棧地址,使用用戶棧;當進程在內核空間時,cpu堆棧指針寄存器裡面的內容是內核棧空間地址,使用內核棧。

2.進程用戶棧和內核棧的切換

當進程因為中斷或者系統調用而陷入內核態之行時,進程所使用的堆棧也要從用戶棧轉到內核棧。

進程陷入內核態後,先把用戶態堆棧的地址保存在內核棧之中,然後設置堆棧指針寄存器的內容為內核棧的地址,這樣就完成了用戶棧向內核棧的轉換;當進程從內核態恢復到用戶態之行時,在內核態之行的最後將保存在內核棧裡面的用戶棧的地址恢復到堆棧指針寄存器即可。這樣就實現了內核棧和用戶棧的互轉。

那麼,我們知道從內核轉到用戶態時用戶棧的地址是在陷入內核的時候保存在內核棧裡面的,但是在陷入內核的時候,我們是如何知道內核棧的地址的呢?

關鍵在進程從用戶態轉到內核態的時候,進程的內核棧總是空的。這是因為,當進程在用戶態運行時,使用的是用戶棧,當進程陷入到內核態時,內核棧保存進程在內核態運行的相關信心,但是一旦進程返回到用戶態後,內核棧中保存的信息無效,會全部恢復,因此每次進程從用戶態陷入內核的時候得到的內核棧都是空的。所以在進程陷入內核的時候,直接把內核棧的棧頂地址給堆棧指針寄存器就可以了。

3.內核棧的實現

內核棧在kernel-2.4和kernel-2.6裡面的實現方式是不一樣的。

在kernel-2.4內核裡面,內核棧的實現是:

Uniontask_union{
Structtask_structtask;
Unsignedlongstack[INIT_STACK_SIZE/sizeof(long)];
};

其中,INIT_STACK_SIZE的大小隻能是8K。

內核為每個進程分配task_struct結構體的時候,實際上分配兩個連續的物理頁面,底部用作task_struct結構體,結構上面的用作堆棧。使用current()宏能夠訪問當前正在運行的進程描述符。

注意:這個時候task_struct結構是在內核棧裡面的,內核棧的實際能用大小大概有7K。

內核棧在kernel-2.6裡面的實現是(kernel-2.6.32):

Unionthread_union{
Structthread_infothread_info;
Unsignedlongstack[THREAD_SIZE/sizeof(long)];
};

其中THREAD_SIZE的大小可以是4K,也可以是8K,thread_info佔52bytes。

當內核棧為8K時,Thread_info在這塊內存的起始地址,內核棧從堆棧末端向下增長。所以此時,kernel-2.6中的current宏是需要更改的。要通過thread_info結構體中的task_struct域來獲得於thread_info相關聯的task。更詳細的參考相應的current宏的實現。

structthread_info{
structtask_struct*task;
structexec_domain*exec_domain;
__u32flags;
__u32status;
__u32cpu;
…..
};

注意:此時的task_struct結構體已經不在內核棧空間裡面了。


如若滿意,請點擊右側【採納答案】,如若還有問題,請點擊【追問】

希望我的回答對您有所幫助,望採納!

~ O(∩_∩)O~

Ⅹ Linux系統調用詳解(如何從用戶空間進入內核

其實進程在內核態和用戶態各有一個堆棧。運行在用戶空間時進程使用的是用戶空間中的堆棧,而運行在內核空間時,進程使用的是內核空間中的堆棧。所以說,Linux 中每個進程有兩個棧,分別用於用戶態和內核態。我其實也不是很理解,如果你想更理解的話可以看下這篇文章,上面講的很詳細網頁鏈接希望對你有幫助啊

閱讀全文

與linux內核空間堆棧相關的資料

熱點內容
壓縮文件鏈接怎麼編輯 瀏覽:808
如何鎖定PDF文件里的圖章 瀏覽:89
資料庫超時是什麼 瀏覽:649
文件怎麼改整列內容 瀏覽:764
360壓縮文件發郵件空白 瀏覽:813
上哪裡查自己大數據 瀏覽:907
編程語言怎麼學車 瀏覽:189
編程該怎麼學才能先找工作 瀏覽:524
文件刻制光碟多少錢 瀏覽:861
校園網的網路組成結構 瀏覽:862
u盤系統復制文件過大 瀏覽:843
區域網復制文件 瀏覽:574
2007cad怎麼編程 瀏覽:325
修改bat文件名 瀏覽:830
cad文件丟失怎麼找回備份 瀏覽:851
手機怎麼獲取無線密碼 瀏覽:315
cad文字版教程 瀏覽:701
16進制讀取文件 瀏覽:831
ps電腦新建文件建不了怎麼辦 瀏覽:60
濟南招標文件圖紙押金一般為多少 瀏覽:113

友情鏈接