站內搜尋

2008/8/29

The trap of Blocking-mode APIs

==========  阻斷式 API 引發的陷阱  ==========
今天解決了一個由阻斷式 API 所引發的 bug,而其中過程曲折離奇,特別在此做一個 note ,也和大家分享一下。 Enjoy it.


今天在上班的時後,幫同事看了二個好玩的 issue,其中一個,因為過程有趣,特別在這裡和大家分享。
相信許多玩過 DOS 的工程師們都用過 printf (or cout) 這簡單的輸出機制來進行一些簡單的 debug 動作,而在 windows 時代呢?
雖然沒有 console,但是我們有 IDE 的 output windows,printf 依然是一個簡單有力的 debug 方式。( 當然,在此,我並不打算談有關 exceptional 的相關機制。
許多時候,我們只是簡單的希望 output 某些資訊來做 debug 的小動作。)
而當場景轉換到手持行動裝置時呢?

當然,依然有許多很棒的方式來進行 run-time 的 debug。
但我也相信會有許多人會簡單的使用 messagebox 來進行一個資訊的輸出。
但,它是一個危險的 blocking-mode APIs。

------------
今天同事發生了一個很靈異的事情。
而這件靈異的事,起因於二個很逗的誤會,是的,一切都只是誤會....
因為工作需要,他必需撰寫一隻被 IE 所載入的 DLL 檔。

而由於對其中機制並未完全的了解,他為了能夠測知物件的執行狀況,
在許多程式段,都插入了 messagebox 這支小小的 API 來 進行狀態確認。
好玩的來了,下午的時後,他帶著一臉疑惑,跑來問我:
「很奇怪,我的 DLL 明明被載入了,但是我的 dllmain 卻沒有跑起來!可是,等到我把 IE 關掉了之後,它才開始跑!為什麼?」
=.=b 說實在,當下我心裡的 OS 是「幹,你嚇不倒我滴!」
最好是還有 dllmain 會看你 IE 被關掉才去跑,現在是在跑單工就對了啦....
詳細問他怎麼做出這種判斷的,他說:
「我在 dllmain 裡有寫 messagebox,在執行的時後,我看 task,DLL 有被載入,但 messagebox 卻沒有跑出來,可是我一關掉 IE,messagebox 才跑出來了。」
相信有許多人都會有不可思議的感覺,最好是 DLL 被載入,但是 dllmain 卻完全沒跑到。

思考了一下,再詳細的問問他實測的內容,直覺的認為是和 blocking-mode 的  messagebox 有關,但當時也沒多想,畢竟 messagebox 也沒跑出來,感覺上就算被 block 住,也該會跑出來才停。
好吧,不管,我簡單的和同事講解了一下何謂 blocking-mode,然後跟她說,我認為這樣判斷太多因素要考慮了,請他改用設定一個 registry key value 的方式,來確認 dllmain 到底是否真的沒被載入。然後我就開始忙我自己份內的事情了.....

..........過了大約一小時...........

因為手頭的事情告了一段落,然後站起來看看那位同事還是一臉疑惑,於事基於自己白爛多管閒事的個性,便跑過去關心了一下,結果他測試的結果是:
「 dllmain 真的是 IE 關掉才載入,registry 是 IE 關掉才設進去的。」
凸,那有可能  <--- 這是我心裡的 OS ..

又基於我不死心的個性,於是我便請她 demo 一次給我看。
看著她的操作,想啊想啊想....突然我靈光一閃!
各位,謎底揭曉前,要不要猜猜發生了什麼事情呢?

............... 時間到 ...............

啊!靠妖呀!一切都只是誤會呀!
其實他的 messagebox 早就出現了,但當它 display 出來之後,不知為何,IE 卻又取回了 focus,而 messagebox 便被推到 background 去。

於是,便產生了 IE 關掉 messagebox 才出現的誤會。

而也因為 messagebox 是 blocking-mode API,因此,它的 DLL 被 hold 在 dllmain,自然沒被載入成功,也就被誤會成 DLL 中的功能完全無效。

好,那,這時我就產生了一個很幹的疑惑,那 registry 咧?
如果是因為 messagebox 的關係,那 registry 該早就被設進去了呀?

一問之下才知道.......
這位天才同事,並沒有把 messagebox 拿掉,而把 set registry 的 code 放在 messagebox 下面 .................................

凸,真有你的.......

這件事,到此,宣布結案......不過結的很搞笑就是了........
---------------

其實,這只是一個 blocking-mode APIs 所引發的誤判的簡單例子。
但卻很可能造成經驗不足的設計師被徹底的卡住,而因為產生的狀況都被誤判,自然不可能問出「正確」的問題,也不可能得到解答。

從上面的例子,可以發現,「分析問題」其實是工程師非常需要具備的一種能力,如何從一大個謎團中找出線索、進而縮小範圍,找出問題所在正是每一名工程師都應該去加強訓練的。
雖然這種能力可能並非一朝一夕之功,但總是該努力的去培養的。

以上分享了這個 blocking-mode APIs 所引發的「分析陷阱」,希望能對大家有所幫助。

沒有留言:

張貼留言

熱門文章