Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 39 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 12
表示系統中總共有 12 個邏輯 CPU(或線程)。
On-line CPU(s) list: 0-11
表示編號從 0 到 11 的所有邏輯 CPU 均已啟動且在線。
Vendor ID: GenuineIntel
表示 CPU 的供應商是 Intel。
Model name: Intel® Core™ i7-10750H CPU @ 2.60GHz
顯示具體的 CPU 型號和頻率。
CPU family: 6, Model: 165, Stepping: 2
這些是 Intel 內部用來標識 CPU 系列、型號與製程版本的資訊。
Thread(s) per core: 2
表示每個物理核心支援 2 個線程(超執行緒技術,Hyper-Threading)。
Core(s) per socket: 6
表示每個 CPU 插槽中有 6 個物理核心。
Socket(s): 1
表示系統中只有一個 CPU 插槽,也就是只有一顆物理 CPU。
BogoMIPS: 5184.01
這是一個用來粗略衡量 CPU 速度的指標,不過主要用於內部參考,並非精確的性能測量。
contributed by < BennyWang1007
>
yy214123
在 queue.h
中已有:
所以不用另外定義:
q_new
可以如下改善:
如此更貼近 linux 核心風格。
q_delete_mid
除了使用快慢指標的策略,也能使用另一個策略來實作:
由於使用的資料結構是環狀雙向串列,這個策略可以減少 次走訪次數。
q_swap
是 q_reverseK
(當 k 為 2)的一個例子,可以直接呼叫 q_reverseK(head, 2)
來重用程式碼。
Request followed 2025 年 Linux 核心設計/實作課程作業 —— lab0
queue.[ch]
以完成 make test
自動評分系統的所有項目
qtest
實作的記憶體錯誤,搭配 Massif 視覺化shuffle
, 參考 Fisher–Yates shuffleqtest
中執行 option entropy 1
並搭配 ih RAND 10
,觀察亂數字串分佈由於先前 commit 未符合CONTRIBUTING.md 的規範與七條原則,我針對相對應 commit 進行 git rabase -i
加以修正。
首先,針對原先第一條 commit,我應當將 q_new
, q_free
與 q_insert_head
, q_insert_tail
分別置於兩則不同 commit,以達到CONTRIBUTING.md 中 Git commit style 所要求之
Each commit should encapsulate a single, coherent change.
以下是更正過後的 commit:
第二則 commit 應當說明實作手法,例如讓 q_insert_head
和 q_insert_tail
共用程式碼片段。注意 CONTRIBUTING.md 的規範:
Use the body to explain what and why, not how.
再者,對於本來的第二條 commit,我應避免濫用 finish 一詞:
to complete something or come to the end of an activity:
q_remove_head
和 q_remove_tail
仍有改進空間。在工程領域,不要輕易說 "finish"。
以下是更正後的 commit :
commit 91aca2d
最後,對於原來的第三則 commit,我改進英語書寫。並遵循 CONTRIBUTING.md 的規範,針對 "what" 與 "how" 進行著重探討。
以下是更正後的 commit :
commit 3769f55
clang-format的使用範例
Function objective : make a empty queue
作法:
LIST_HEAD
做出一頭節點INIT_LIST_HEAD
宏初始化這個頭節點Function objective : free whole queue
作法
head
是 NULL,直接返回。list_for_each_entry_safe
遍歷佇列中的每個 element_tlist_del
將節點從鏈表中移除。q_release_element
釋放節點的記憶體作法 :
new
。new
s
到 new
。strncpy
失敗,釋放 new
並返回 false。new
插入到 head
的後面。增加動態分配記憶體與 strncpy
後的memory allocation validation
作法 :
與 q_insert_head
邏輯相同
增加動態分配記憶體與 strncpy
後的memory allocation validation
作法:
sp
不為 NULL,用 strncpy
將移除元素的 value 複製到 sp
中,並末尾保留位置設置字串終止符 \0
。字串增加設置以 \0
結尾,確保了安全性與一致性,解決會導致未定義行為的可能性
作法 :
與 q_remove_tail
同
字串增加設置以 \0
結尾,確保了安全性與一致性,解決會導致未定義行為的可能性
作法
head
的每個節點作法 :
slow
和 fast
指針,初始都指向第一個元素fast
以 slow
兩倍stride前進如果 fast
快到末尾,則中間節點是 slow->next,移除它。修改未適當釋放element記憶體的部分
根據 leetcode 82. Remove Duplicates from Sorted List II 要求,須將重複的val之node全刪除。若是只刪除重複的node,較為容易,因此轉而思考如何將多的那個node刪除。最後參考 王漢棋 同學實作,使用 flag
觀念。
list_for_each_safe
遍歷若用list_for_each_entry_safe遍歷就不需要釋放記憶體時都要再 list_entry()
使用此函式做"向上轉型"
作法:
swap2node
,用來交換兩個相鄰節點:count
count
== 2 時,調用 swap2node
交換當前節點和前一個節點,然後重置 count
為 0。將 swap2node
函式移到外面消除nested function warning
作法 :
next
、 prev
方向head
的 next
、 prev
完成reverse用到之list.h函式講解:
傳入的引數
list
所要接入的點(必須為empty)list
的開始nodelist
結尾nodelist
插入到另外一條中LIST_HEAD()
函式對 list
做初始化,把next、prev洗掉我以merge_sort實作q_sort
Merge Sort 核心原理 :
分割 (Divide):
將鏈結串列不斷地對半分,直到每個子串列只剩下一個節點(或空串列)。一個節點的串列自然就是已排序的。
解決 (Conquer):
合併 (Combine):
合併兩個已排序串列 (Merge Two Sorted Lists):
在過程中我遇到兩個問題
修改成set = condition時chosen_list_ptr 先拿left的,即可不更動重複case的相對位置
trace-03-ops
時 sort 總是無法順利進行,輸出如下:merge_sort
時其實僅僅只對 next
做正確設置,並沒有對每個 element 的 prev
進行設置。我沒注意到此事,因此在 q_sort
完我僅僅將頭尾重接,卻並 沒管理到每個element_t的 prev
部分。導致若之後對此q_sort完的queue進行處理,會有極大機率會產生segmentation fault在更改完,在遍歷時利用正確的next
,將每個element
的prev
管理設置正確,最後頭尾接回後即測試成功
首先根據leetcode 2487. Remove Nodes From Linked List我參考了這部影片
講者提出總共四種策略
第一種
最直觀方法但效率低下 ( O(n^2) ):
作法:
第二種
"壞節點" 陣列 ( O(n) 時間、O(n) 空間):
作法 :
suffix_max
變數,記錄目前為止(從右向左看)的最大值。suffix_max
,就將其標記為「壞的」(需要移除)。這種方法的時間複雜度是 O(n)(兩次遍歷),空間複雜度是 O(n)(用於儲存 suffix_max
或「壞節點」陣列)。
第三種
堆疊Stack ( O(n) 時間、O(n) 空間)
作法 :
第四種
linked list最佳方法 ( O(n) 時間, O(1) 空間 ) :
講者最終提出了適用於 linked-list 的高效方法:
作法 :
max_so_far
變數,初始值設為第一個節點(原來的尾端節點)的值。max_so_far
,則移除它(使用標準的鏈結串列節點移除方法:調整前後節點的指標)。max_so_far
),則將 max_so_far
更新為當前節點的值。根據第四種方法,就是從尾部逆向遍歷,且維護一個全局最大值 max_so_far
小於他則delete,大於他則更新。但linux linked-list結構是doubly,因此不需要像leetcode作法一樣做兩次reverse,即可直接逆向遍歷。
q_descend
作法流程 :
max_so_far
小於他則delete,大於他則更新
max_so_far
為指向char之指標若是將相等與小於分開判斷,能夠避免相等後又跑一遍 max_so_far = list_entry(trav, element_t, list)->value;
值帶入,或許效能較好。
目的是與 q_descend
相反,刪除右邊所有比本身node小的所有node。因此邏輯與 q_descend
完全相同,將判斷式改變即可。
參考蔡忠翰的實作
作法 :
LIST_HEAD
定義一個臨時雙向鏈結串列 temp,並透過 INIT_LIST_HEAD
初始化其結構。list_for_each_entry_safe
遍歷 head
中的每個 queue_contex_t 節點(透過 chain
成員連結),並將每個節點的佇列(trav
->q
)拼接至 temp
。q_sort
,對 temp
中的所有元素進行排序,根據 descend
決定升序或降序。temp
佇列拼接回 head
中第一個 queue_contex_t 節點的佇列並清空 temp
。q_size
返回合併後佇列的總元素數量。根據 N01: lab0 以 Valgrind 分析記憶體問題 ,memory leak 分為四種 :
definitely lost
: 真的 memory leakindirectly lost
: 間接的 memory leak,structure 本身發生 memory leak,而內部的 member 如果是 allocate 的出來的,一樣會 memory leak,但是只要修好前面的問題,後面的問題也會跟著修復。possibly lost: allocate
一塊記憶體,並且放到指標 ptr,但事後又改變 ptr 指到這塊記憶體的中間still reachable
: 程式結束時有未釋放的記憶體,不過卻還有指標指著,通常會發生在 global 變數,即便是在所用的函式庫裡頭配置的記憶體,也可偵測到,這也是動態分析手法的優勢。用 valgrind
跑 trace-03-ops.cmd 測資,此為test中第一個出現fail且非效能測試
+++ TESTING trace trace-03-ops:
Test of 'q_new', 'q_insert_head', 'q_remove_head', 'q_reverse', 'q_sort', and 'q_merge'
86422 Stack overflow in thread #1: can't grow stack to 0x1ffe801000
86422 Stack overflow in thread #1: can't grow stack to 0x1ffe801000
86422 Can't extend stack to 0x1ffe8010b8 during signal delivery for thread 1:
86422 no stack segment
86422
86422 Process terminating with default action of signal 11 (SIGSEGV)
86422 Access not within mapped region at address 0x1FFE8010B8
86422 Stack overflow in thread #1: can't grow stack to 0x1ffe801000
86422 at 0x11047E: merge_sort (queue.c:271)
86422 If you believe this happened as a result of a stack
86422 overflow in your program's main thread (unlikely but
86422 possible), you can try to increase the size of the
86422 main thread stack using the –main-stacksize= flag.
86422 The main thread stack size used in this run was 8388608.
86422 6 bytes in 1 blocks are still reachable in loss record 1 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E3D7: strsave_or_fail (report.c:256)
86422 by 0x10ECF3: parse_args (console.c:154)
86422 by 0x10ECF3: interpret_cmd (console.c:233)
86422 by 0x10EFC0: cmd_select (console.c:604)
86422 by 0x10F8A1: run_console (console.c:684)
86422 by 0x10DB20: main (qtest.c:1441)
86422
86422 8 bytes in 1 blocks are still reachable in loss record 2 of 45
86422 at 0x484D953: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E344: calloc_or_fail (report.c:234)
86422 by 0x10ECC5: parse_args (console.c:151)
86422 by 0x10ECC5: interpret_cmd (console.c:233)
86422 by 0x10EFC0: cmd_select (console.c:604)
86422 by 0x10F8A1: run_console (console.c:684)
86422 by 0x10DB20: main (qtest.c:1441)
86422
86422 32 bytes in 1 blocks are still reachable in loss record 3 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10D126: do_new (qtest.c:151)
86422 by 0x10E97E: interpret_cmda (console.c:214)
86422 by 0x10ED28: interpret_cmd (console.c:234)
86422 by 0x10EFC0: cmd_select (console.c:604)
86422 by 0x10F8A1: run_console (console.c:684)
86422 by 0x10DB20: main (qtest.c:1441)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 4 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10F3C6: init_cmd (console.c:436)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 5 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10F3E7: init_cmd (console.c:437)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 6 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10F404: init_cmd (console.c:440)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 7 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10F428: init_cmd (console.c:441)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 8 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10F445: init_cmd (console.c:442)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 9 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10F466: init_cmd (console.c:443)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 10 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10F487: init_cmd (console.c:444)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 11 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10F4A8: init_cmd (console.c:445)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 12 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10F4C7: init_cmd (console.c:446)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 13 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10F4E6: init_cmd (console.c:447)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 14 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10F505: init_cmd (console.c:448)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 15 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10F524: init_cmd (console.c:449)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 16 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10F543: init_cmd (console.c:450)
86422 by 0x10D824: main (qtest.c:1420)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 17 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D848: console_init (qtest.c:1061)
86422 by 0x10D848: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 18 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D865: console_init (qtest.c:1062)
86422 by 0x10D865: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 19 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D882: console_init (qtest.c:1063)
86422 by 0x10D882: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 20 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D89F: console_init (qtest.c:1064)
86422 by 0x10D89F: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 21 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D8C3: console_init (qtest.c:1065)
86422 by 0x10D8C3: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 22 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D8E0: console_init (qtest.c:1069)
86422 by 0x10D8E0: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 23 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D904: console_init (qtest.c:1073)
86422 by 0x10D904: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 24 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D921: console_init (qtest.c:1077)
86422 by 0x10D921: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 25 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D93E: console_init (qtest.c:1081)
86422 by 0x10D93E: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 26 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D95B: console_init (qtest.c:1082)
86422 by 0x10D95B: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 27 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D97C: console_init (qtest.c:1083)
86422 by 0x10D97C: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 28 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D999: console_init (qtest.c:1084)
86422 by 0x10D999: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 29 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D9B6: console_init (qtest.c:1085)
86422 by 0x10D9B6: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 30 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D9D3: console_init (qtest.c:1086)
86422 by 0x10D9D3: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 31 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10D9F0: console_init (qtest.c:1087)
86422 by 0x10D9F0: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 32 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10DA0D: console_init (qtest.c:1088)
86422 by 0x10DA0D: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 33 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10DA2A: console_init (qtest.c:1089)
86422 by 0x10DA2A: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 34 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10DA4A: console_init (qtest.c:1093)
86422 by 0x10DA4A: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 35 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F028: add_cmd (console.c:85)
86422 by 0x10DA6B: console_init (qtest.c:1097)
86422 by 0x10DA6B: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 36 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10DA8A: console_init (qtest.c:1099)
86422 by 0x10DA8A: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 37 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10DAA9: console_init (qtest.c:1101)
86422 by 0x10DAA9: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 38 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10DAC8: console_init (qtest.c:1103)
86422 by 0x10DAC8: main (qtest.c:1421)
86422
86422 40 bytes in 1 blocks are still reachable in loss record 39 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10F0AC: add_param (console.c:105)
86422 by 0x10DAE3: console_init (qtest.c:1105)
86422 by 0x10DAE3: main (qtest.c:1421)
86422
86422 64 bytes in 2 blocks are possibly lost in loss record 40 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10D126: do_new (qtest.c:151)
86422 by 0x10E97E: interpret_cmda (console.c:214)
86422 by 0x10ED28: interpret_cmd (console.c:234)
86422 by 0x10EFC0: cmd_select (console.c:604)
86422 by 0x10F8A1: run_console (console.c:684)
86422 by 0x10DB20: main (qtest.c:1441)
86422
86422 168 bytes in 3 blocks are still reachable in loss record 41 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10F92D: alloc (harness.c:146)
86422 by 0x10FA80: test_malloc (harness.c:176)
86422 by 0x10FDCE: q_new (queue.c:10)
86422 by 0x10D15F: do_new (qtest.c:155)
86422 by 0x10E97E: interpret_cmda (console.c:214)
86422 by 0x10ED28: interpret_cmd (console.c:234)
86422 by 0x10EFC0: cmd_select (console.c:604)
86422 by 0x10F8A1: run_console (console.c:684)
86422 by 0x10DB20: main (qtest.c:1441)
86422
86422 378 bytes in 9 blocks are still reachable in loss record 42 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10F92D: alloc (harness.c:146)
86422 by 0x10FA80: test_malloc (harness.c:176)
86422 by 0x10FC41: test_strdup (harness.c:231)
86422 by 0x10FE8E: q_insert_head (queue.c:40)
86422 by 0x10CEEB: queue_insert (qtest.c:234)
86422 by 0x10D0BC: do_ih (qtest.c:282)
86422 by 0x10E97E: interpret_cmda (console.c:214)
86422 by 0x10ED28: interpret_cmd (console.c:234)
86422 by 0x10EFC0: cmd_select (console.c:604)
86422 by 0x10F8A1: run_console (console.c:684)
86422 by 0x10DB20: main (qtest.c:1441)
86422
86422 576 bytes in 9 blocks are still reachable in loss record 43 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10F92D: alloc (harness.c:146)
86422 by 0x10FA80: test_malloc (harness.c:176)
86422 by 0x10FE6D: q_insert_head (queue.c:36)
86422 by 0x10CEEB: queue_insert (qtest.c:234)
86422 by 0x10D0BC: do_ih (qtest.c:282)
86422 by 0x10E97E: interpret_cmda (console.c:214)
86422 by 0x10ED28: interpret_cmd (console.c:234)
86422 by 0x10EFC0: cmd_select (console.c:604)
86422 by 0x10F8A1: run_console (console.c:684)
86422 by 0x10DB20: main (qtest.c:1441)
86422
86422 1,024 bytes in 1 blocks are still reachable in loss record 44 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x49D01B4: _IO_file_doallocate (filedoalloc.c:101)
86422 by 0x49E0523: _IO_doallocbuf (genops.c:347)
86422 by 0x49DDF8F: _IO_file_overflow@@GLIBC_2.2.5 (fileops.c:745)
86422 by 0x49DEAAE: _IO_new_file_xsputn (fileops.c:1244)
86422 by 0x49DEAAE: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1197)
86422 by 0x49ABCC8: __printf_buffer_flush_to_file (printf_buffer_to_file.c:59)
86422 by 0x49ABCC8: __printf_buffer_to_file_done (printf_buffer_to_file.c:120)
86422 by 0x49B6742: __vfprintf_internal (vfprintf-internal.c:1545)
86422 by 0x10E1F0: vfprintf (stdio2.h:109)
86422 by 0x10E1F0: report_noreturn (report.c:142)
86422 by 0x10E62F: do_comment_cmd (console.c:289)
86422 by 0x10E97E: interpret_cmda (console.c:214)
86422 by 0x10ED28: interpret_cmd (console.c:234)
86422 by 0x10EFC0: cmd_select (console.c:604)
86422
86422 8,216 bytes in 1 blocks are still reachable in loss record 45 of 45
86422 at 0x4846828: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
86422 by 0x10E2C9: malloc_or_fail (report.c:215)
86422 by 0x10EB06: push_file (console.c:471)
86422 by 0x10F77B: run_console (console.c:662)
86422 by 0x10DB20: main (qtest.c:1441)
86422
主要問題:Stack Overflow
報告中提到以下關鍵錯誤:
具體出現在 merge_sort 函數中(位於 queue.c 文件的第 271 行)。程式試圖使用超出分配stack大小的記憶體空間。在這裡,程式嘗試將stack擴展到地址 0x1ffe801000
,但失敗了,因為該地址超出了映射的記憶體區域。這導致程序試圖存取無效記憶體地址 0x1ffe8010b8
,引發了分段錯誤(SIGSEGV=segmentation fall),最終導致程序終止。
如果遞迴深度超過這個限制,就會觸發stack overflow。
有45 個 still reachable
的記憶體塊
這些記憶體在程序結束時未被釋放
這些記憶體塊是程式分配的,但直到程序終止時仍未釋放。它們被標記為 still reachable
,它們仍然有指針指向這些記憶體,不是記憶體洩漏(memory leak)。這些記憶體的大小從 6 字節到 8,216 字節不等,分別在不同函數中分配,例如 strsave_or_fail
、calloc_or_fail
、do_new
和 push_file
等。由於程式因stack overflow異常終止,這些記憶體未被正常釋放是預期之內的。當程序退出時,作業系統會自動回收這些記憶體
首先我懷疑是 q_merge
出現問題於是單獨測試功能但都正常。後來才懷疑到是用到的 q_sort
有問題,詳情在q_sort遇到問題二
這邊參考 alanjiang85 所表示需挑選適當的測試資料時要避免效能類型的測試,因為以 Valgrind 執行測試程式會比較慢,容易導致出現超過時間限制的狀況。因此最後用 trace-eg.cmd
進行分析
i
i
表示時間單位,通常代表程式執行的指令數量(instructions),記憶體使用情況是根據指令執行次數來記錄的。snapshots
:9peak
: snapshot # 6 after 290678 "i"分配來源:峰值記憶體主要與文件操作(_IO_file_doallocate
和 fdopen
)相關
出現錯誤訊息像
可能是圖形驅動或環境配置的問題。
因此之後改用 ms_print
工具在終端查看 Massif 輸出,生成一個文字版的記憶體使用報告,包含曲線和分配細節
lib/list_sort.c
並引入專案參考 , chiangkd, Risheng, hanchi , jeremy
閱讀 lib/list_sort.c
筆記額外放在這Lab0 lib/list_sort.c 研讀筆記
list_sort.c
加入專案lab0_C
專案中list_sort.c
中用到的 macro 加入到 list_sort.h
中likely
, unlikely
加入 list_sort.h
header中Makefile
中的 OBJS 中新增 list_sort.o
修改 qtest.c
這個檔案
qtest.c
的開頭加入以下行list_sort
do_sort
函數,根據 use_list_sort
選擇排序方法list_sort
選項到help選單:這允許用戶通過命令 option listsort 1 啟用 list_sort,或 option listsort 0 回到 q_sort
編寫一測資 trace-sort-cp.cmd
測試實作之q_sort
與list_sort
執行時間差異
輸入
即可得到 list_sort
或 sort
的處理時間
可看到 q_sort
、 list_sort
所花時間分別為 1.289s、0.946s
透過以下命令來查看使用 perf 的權限
如果想要把權限全部打開的話,可以使用這條指令,且將值設為 -1
再來可以輸入以下來確認自己是否有拿到最高權限值 (如果以非 root 用戶運行 perf top,通常會收到類似「Permission denied」或「perf_event_open() failed」的錯誤訊息)
首先我在trace目錄下家兩個測試命令集用來測試分別用來對 q_sort 與 list_sort
可以使用以下指令來取得 cache-misses
, cache-references
, instructions
, cycles
這些項目的資訊
shuffle