最近工作中遇到乙個問題,前前後後共定位了4天+,當最後定位到根因的時候,才發現「最後出問題的地方往往是那些你認為最不會出問題的地方」這句話是警示名言,要牢記之。
問題場景:有一大片記憶體,從起始位址開始以128kb大小切塊(低位址的64kb記憶體設定為唯讀,高位址的64kb記憶體主要用於任務棧),大概有205000個;現在寫個函式從低位址開始把每個棧的低位址寫入陣列。
**大概如下:
unsigned
int stack_size = 65536;
void* statck_init(void* stack_start_addr,int num)
stack_array = (void**)malloc(sizeof(void*)*20500);
if (!stack_array)
for(i=0;i<205000;i++)
return (void*)statck_array;
}
在執行業務過程中大概率出現同一片棧的記憶體被同時被兩個任務執行,開始以為棧分配和釋放流程中沒有做好互斥,所以對棧使用的場景的**進行詳細**檢視和加除錯資訊,但是問題還是沒有定位出來。
在定位問題期間,也有懷疑到上述**可能有問題,但是**如此簡單,不會出問題,也拉多人檢視。
但是最終多人同時分析**時,突然發現:
stack_array[i] = stack_start_addr + stack_size*2
*i;
**中存在問題:stack_size*2*i可能溢位;
unsigned int的最大值是4294967295
當i為100000時:stack_size*2*i的值是13107200000,此時對unsigned int的資料型別來說已經溢位,所以stack_array中存在多個同乙個位址,所以從陣列中取的位址存在重複。
1.檢視**時多關注邊界問題,陣列溢位,位址溢位,資料型別溢位等。
2.最不可能出現問題的**往往就是問題的根因。
3.檢視**不能因為簡單而跳過。
乙個餘數問題的思考
剛剛在貼吧上看到乙個很簡單的演算法小問題,順便看到了很多人不同的思路。我覺得很有意思,所以也來研究一下。問題如下 一筐雞蛋 1個1個拿,正好拿完。2個2個拿,還剩1個。3個3個拿,正好拿完。4個4個拿,還剩1個。5個5個拿,還差1個。6個6個拿,還剩3個。7個7個拿,正好拿完。8個8個拿,還剩1個。...
乙個簡單的遞迴演算法的思考
一 遞迴演算法的概述 遞迴演算法的描述 把乙個大規模的問題劃分為乙個個小規模的同類問題的子問題。遞迴演算法的特徵 1 在函式中呼叫其本身 2 必須有乙個明確的遞迴出口 3 遞迴結果的輸出是乙個堆疊結構,最後的結果最先輸出,最初的結果最後輸出。二 乙個簡單的遞迴演算法的思考 思考一 遞迴語句最後的輸出...
乙個生產問題引發的思考
前言 最近碰到乙個生產問題,整個處理過程讓我不禁想起幾年前碰到的乙個類似情景,但是結果卻完全不一樣。兩次問題說大不大,說小不小。這次由於我們處理及時,大事化小小事化了而已,然而幾年前的那次事件,卻由於多方原因,鬧得挺大,驚動了某會。由此引發的一些思考和總結吧。問題回顧 排查思路 生產出現這種效能問題...