線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:5268
推到 Plurk!
推到 Facebook!

兩支exe之間的主從關係

缺席
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#1 引用回覆 回覆 發表時間:2012-09-23 21:25:13 IP:220.136.xxx.xxx 未訂閱
各位好:

上一篇我提到 exe call dll 會引發錯誤, 我把 dll 改成了 exe

由 a.exe call b.exe , 使用 ShellExecute() 的指令, 而且是掛在 a.exe 啟動後會自動進行
當 a.exe 在 call b.exe 之後, 我隨即關閉 a.exe 程式, 只保留 b.exe 在記憶體中, 但這樣的呼叫方式卻造成
在某一些電腦(指某一些即是不特定的電腦, 也不特定的作業系統, win7, win2003, winxp, vista..) , 只要 b.exe 結束
就會引發 Access Error 錯誤, 或者 已經把b.exe釋放了, 也沒有錯誤, 但在 process 中 b.exe 仍然掛在上面(在win7特別容易出現)
但在有一些電腦卻怎麼都不會發生,
目前已測試了約40台電腦, 發生率約在10台左右,
所以想請問, a.exe call b.exe 是否有主從關係的存在, 這樣的呼叫不能把 a.exe 先釋放,
因為我後來做了測試

a.exe call b.exe (a.exe不close), 由b.exe 在close同時, 關閉 a.exe, 結果竟然不會造成錯誤,
又另外, 我把 a.exe 加入一組 button, 由 button中呼叫 b.exe, 這樣的做法, 當 b.exe close時也不會引發錯誤,
而再把 a.exe 也 close, 一切正常,
所以讓我懷疑, a.exe call b.exe , 雖然是兩支exe的運作, 但 ShellExecute 仍然會造成主從關係,
在記憶體的堆疊中仍有先後關連, 而 b.exe close時, 如果 a.exe 不存在, 則造成記憶體無法被釋放引發錯誤,
這我是測試下來認為最大的可能性,
但如果我希望 a.exe call b.exe 後, a.exe 要被結束的話, 還有其他方法嗎?
jcjroc
高階會員


發表:21
回覆:279
積分:115
註冊:2002-09-18

發送簡訊給我
#2 引用回覆 回覆 發表時間:2012-09-23 23:32:17 IP:60.248.xxx.xxx 訂閱
CreateProcess
WinExec也可以
你是不是a有傳資料給b????
1.如果有,那你可要等確認b已經把資料給讀取了才行
2.如果b還可能傳資料給a,那b必須確認a是否還存在
3.(1)成立,如果有Handle性質的東西,要先複製再傳給b用(當然DuplicateHandle的第三個參數要是b的process handle)

如果上述(1)猜得沒錯,你應該出現在新機器上(效能高的),這時最笨且無賴的方式就是a exec b之後delay一段時間再close

編輯記錄
jcjroc 重新編輯於 2012-09-23 09:53:16, 註解 無‧
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#3 引用回覆 回覆 發表時間:2012-09-24 00:25:16 IP:220.136.xxx.xxx 未訂閱
1.在很多文獻中介紹, WinExec 是要相容於舊版win的指令, 一般都建議我們使用ShellExecute, 但不知WinExec有何限制?
2.兩支程式並沒有傳遞參數
3.Delay一段時間, 我有試過, 並沒有用, 因為在 a.exe 是一支 login程式, 不論等多久, 只要 a.exe 先被關就會錯!

謝謝!
===================引 用 jcjroc 文 章===================
CreateProcess
WinExec也可以
你是不是a有傳資料給b????
1.如果有,那你可要等確認b已經把資料給讀取了才行
2.如果b還可能傳資料給a,那b必須確認a是否還存在
3.(1)成立,如果有Handle性質的東西,要先複製再傳給b用(當然DuplicateHandle的第三個參數要是b的process handle)

如果上述(1)猜得沒錯,你應該出現在新機器上(效能高的),這時最笨且無賴的方式就是a exec b之後delay一段時間再close

jcjroc
高階會員


發表:21
回覆:279
積分:115
註冊:2002-09-18

發送簡訊給我
#4 引用回覆 回覆 發表時間:2012-09-24 00:48:04 IP:60.248.xxx.xxx 訂閱
我好像有點搞錯了你的問題根本!!!
你的根本還是記憶體的非法使用!!!
尤其是使用Delphi(or c builder)Application的CreateForm自動建立的Form最常引發此種狀態
但這並不是VCL的錯,而是工程師的問題(姑且稱之為無心之過吧!!),為了這事我曾下令把每個Form Class的extern PACKAGE TxxForm給我刪掉,option裡的Forms不要給我看到任何一個Auto create forms.
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#5 引用回覆 回覆 發表時間:2012-09-24 09:50:15 IP:118.160.xxx.xxx 未訂閱
感謝說明, 
但不知 為何 Auto Create From 會造成這樣的現象, 因為好像沒有任何一本書有提到一丁點的警告,
我再試試看, 是不是真的是這樣的問題,
搞不好, 我之前 exe call dll 會引發當機也是這個問題呢?
唉! 用了十幾年, 真的完全不知道
===================引 用 jcjroc 文 章===================
我好像有點搞錯了你的問題根本!!!
你的根本還是記憶體的非法使用!!!
尤其是使用Delphi(or c builder)Application的CreateForm自動建立的Form最常引發此種狀態
但這並不是VCL的錯,而是工程師的問題(姑且稱之為無心之過吧!!),為了這事我曾下令把每個Form Class的extern PACKAGE TxxForm給我刪掉,option裡的Forms不要給我看到任何一個Auto create forms.
leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#6 引用回覆 回覆 發表時間:2012-09-24 11:44:37 IP:118.165.xxx.xxx 訂閱
 Delphi的 Auto Create From 只是Application.Initialize後,  
馬上由Application來 CreateForm,預先產生出Not Visivle的Form
Auto太多 程式啟動就會變慢
,設計階段把Form的 Visible屬性設為True 就可以看到Form了
你可以開.dpr檔就可以看到相關的Source
要使用Form物件就是要Create, 設計Auto Create From的用意
就是不需要讓使用者擔心到底有沒有Create Form了
也不需要煩惱Free問題 只要控制Form的Show或Hide就好
此機制適合Form較少 架構較簡單的程式
淺顯易懂 並沒什麼特別
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2012-09-24 17:59:34 IP:101.12.xxx.xxx 訂閱
 pd 兄,請教一下一些深入一點的資訊。

1/ shellexecute之後是否有用使sendmessage之類的api給b?

2/ login的form是自殺,還是被b所殺?

3/ 殺的方式是用? applicaton teminate? form close? 還是別的api?

4/ login是否有對某些檔案或資訊庫做讀寫? 方便b生成後去讀取之類的… 若有,那也許有資源咬住的情形之類的…

如果方便,可以概念性的貼出 shellexecute的前後虛碼與殺的部份的碼,這樣應該很快可以找到答案。
------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
jcjroc
高階會員


發表:21
回覆:279
積分:115
註冊:2002-09-18

發送簡訊給我
#8 引用回覆 回覆 發表時間:2012-09-24 22:13:54 IP:60.248.xxx.xxx 訂閱
工程師的問題(姑且稱之為無心之過吧!!),

問題出在多個Form大都皆有傳遞指標性的Object,或引用的狀況,但隨著程式的複雜與龐大,工程師並不能非常確認目標是否已建立或已摧毀,反正指標不為NULL就當它存活,
所以我才要求把Global的東西給刪了,以此方式逼工程師精確控制每個Object的生命週期.當然除此之外還有其他的配套措施.雖然如此一來增加了工程師程式開發時有許多繁瑣的code要寫,但為了得到一個穩定的軟體,不得不做此一般人看來浪費無意的工.

工程師如果不能精確控制Object的生命週期那真的有點他..................雖然這議題有點複雜又有點簡單.

P.D. 你的問題要徹底解決,我想這是你要蝕把米的地方.或許你會覺得上述並不能解決你眼前的問題,但個人覺得這才是根本解決你的問題的方法.

順帶一提,我控制Object生命週期是利用puer com來做,至於內部記憶體.......有alloc ,那Object摧毀(或function結束)時就free,



===================引 用 P.D. 文 章===================
感謝說明,
但不知 為何 Auto Create From 會造成這樣的現象, 因為好像沒有任何一本書有提到一丁點的警告,
我再試試看, 是不是真的是這樣的問題,
搞不好, 我之前 exe call dll 會引發當機也是這個問題呢?
唉! 用了十幾年, 真的完全不知道
===================引 用 jcjroc 文 章===================
我好像有點搞錯了你的問題根本!!!
你的根本還是記憶體的非法使用!!!
尤其是使用Delphi(or c builder)Application的CreateForm自動建立的Form最常引發此種狀態
但這並不是VCL的錯,而是工程師的問題(姑且稱之為無心之過吧!!),為了這事我曾下令把每個Form Class的extern PACKAGE TxxForm給我刪掉,option裡的Forms不要給我看到任何一個Auto create forms.
編輯記錄
jcjroc 重新編輯於 2012-09-24 08:24:40, 註解 無‧
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#9 引用回覆 回覆 發表時間:2012-09-25 13:54:17 IP:118.160.xxx.xxx 未訂閱
感謝jcjroc兄的指點, 不過j兄所提的知識可能已經超過我所能認知的層級, 若沒有特別指點, 我應該無法完成的, 不過我再想其他的方法看看, 謝謝!
===================引 用 jcjroc 文 章===================
工程師的問題(姑且稱之為無心之過吧!!),

問題出在多個Form大都皆有傳遞指標性的Object,或引用的狀況,但隨著程式的複雜與龐大,工程師並不能非常確認目標是否已建立或已摧毀,反正指標不為NULL就當它存活,
所以我才要求把Global的東西給刪了,以此方式逼工程師精確控制每個Object的生命週期.當然除此之外還有其他的配套措施.雖然如此一來增加了工程師程式開發時有許多繁瑣的code要寫,但為了得到一個穩定的軟體,不得不做此一般人看來浪費無意的工.

工程師如果不能精確控制Object的生命週期那真的有點他..................雖然這議題有點複雜又有點簡單.

P.D. 你的問題要徹底解決,我想這是你要蝕把米的地方.或許你會覺得上述並不能解決你眼前的問題,但個人覺得這才是根本解決你的問題的方法.

順帶一提,我控制Object生命週期是利用puer com來做,至於內部記憶體.......有alloc ,那Object摧毀(或function結束)時就free,
P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#10 引用回覆 回覆 發表時間:2012-09-25 14:06:23 IP:118.160.xxx.xxx 未訂閱
蕭兄, 你這個問題問題太好了, 
我文內沒提到, 如果只是一支單純 shellExecute(), 沒有其他程式碼, 那這個樣子是不會有問題,
現在最大的問題就是當初設計的是一支主exe call dll, 而後因為dll一直有問題, 才想改成 exe 模式,
但前一個問題解決了, 而又冒出這個問題
兩支exe 都有使用到 indyserver, indyclient, socketserver, socketclient, timer,
兩支exe 都有sendmessage 的設計, 但並沒有互相傳遞
兩支都有使用 一些 3'rd party 元件(主要是TMS, KBM)
看起來都好像沒有直接關係, 但只有這兩支會引發問題,
我還有近100支EXE也都是這樣呼叫, 但並不會造成記憶體錯誤的問題
所以我絕對相信是在記憶體控制上沒有釋放, 非法使用, 或其他因素, 但實在不知道是那個地方出了問題,
我曾經把錯誤的地方取消掉(當掉時指向某一元件, 我改用DELPHI 標準元件替換), 但再RUN, 又是另一個元件的錯誤,
所以改不勝改, 只好放棄,
現在我最新的改法是把兩支想辦法合成一支, 也就是不再 A CALL B , 直接把 A 段併入B段中,
目前還在進行觀察中, 但似乎引發錯誤的機率由 100% 已降到 30%以下

至於 A 的 CLOSE , 我都試過, 如
FORMA.CLOSE
APLICATION.TERMINATE,

或由 B 進行的CLOSE A 的動作, 因為 要B抓到 A的 HANDEL 很麻煩, 所以我是直接在 B 中下KILLPROCESS的方式,
把 A.EXE 的執行序直接砍掉, 一開始的一兩天測都還OK, 但過了一段時間, 程式好像有免疫機制, 錯誤又再度出現
==========引 用 aftcast 文 章===================
pd 兄,請教一下一些深入一點的資訊。

1/ shellexecute之後是否有用使sendmessage之類的api給b?

2/ login的form是自殺,還是被b所殺?

3/ 殺的方式是用? applicaton teminate? form close? 還是別的api?

4/ login是否有對某些檔案或資訊庫做讀寫? 方便b生成後去讀取之類的… 若有,那也許有資源咬住的情形之類的…

如果方便,可以概念性的貼出 shellexecute的前後虛碼與殺的部份的碼,這樣應該很快可以找到答案。
RootKit
資深會員


發表:16
回覆:358
積分:419
註冊:2008-01-02

發送簡訊給我
#11 引用回覆 回覆 發表時間:2012-09-25 14:39:10 IP:36.228.xxx.xxx 訂閱
從本身程式是有主從關係,單僅是 Process Information 提供的 LinkList 。如同 Service Record 一樣。
主從關係主要跟 Token 或權限有關。跟記憶體應無關連性。

個人認為 Indy 發生阻塞的可能性最大。或者在 Timer 中沒有保護好物件。
建議可將該功能先關閉。來查察原因。



leveon
資深會員


發表:30
回覆:389
積分:303
註冊:2012-02-12

發送簡訊給我
#12 引用回覆 回覆 發表時間:2012-09-25 15:01:00 IP:118.165.xxx.xxx 訂閱

編輯記錄
leveon 重新編輯於 2012-09-25 01:05:49, 註解 無‧
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#13 引用回覆 回覆 發表時間:2012-09-25 16:54:58 IP:114.32.xxx.xxx 訂閱
我的看法也是覺得indy最有可能造成問題。從你的解說來看,二隻程式唯一有相關的是indy存取某資源,而且可能資源還一樣。其實二隻exe若完全不互動,且不共用外面的資源,理論上是不會誰死影響誰的。

indy是一個阻塞式的socket模式 (可拿我上次講socket的講座講義回憶一下),所以造成問題的可能性更高一點,請確認幾件事:

1/ windows上sever port只能一時間存在一個號碼,比如8080port,當被聽時另一個試著去listen,就會掛點。
2/ client socket的 port也不能重複(通常不會去指定,沒指定就會動態產生,就不會有問題)。
以上二點檢查一下就好,可能不是最可能發生的原因。
3/ sokcet client連出去的請求,若遇到server忙,或掛時… client 可能會咬住一段時間,或整個咬死。而在這個"無回應"的期間,若試著去把exe殺了,可能會造成socket無法釋放,進而exe檔hang在工作管理員上死不了…所以要針對若連不上的情形做處理,且indy會產生thread(自動的),thread沒死也可能造成問題。故在結束form/application時,要在結束前確認indy已經釋放了,否則要等它,或者強制把它幹掉後再結束程式。

講一堆,我先第一要務是,先讓indy暫無作用。試一下後,沒問題的話,應該就是它了…(我實在想不出還有什麼可能性,但還是要試)。從你說40台有幾台會,而且亂數,與平台也無關… 這樣的現象更有可能了。因為os在不同時候,不同機器,處理網路的資源與速度都會不一樣,當然你server上的indy處理事情的忙度也是亂數…再再都有指向indy是問題的跡象!

此外,sendmessage也是要小心一點的,不過應該機率很小。因為sendmessage也會造成阻塞的情形,若在阻塞的情形下你去釋放或將程式關了…有一點小機會會lock住,永遠死不了…又hang在工作管理員上。

以上是我的看法,希望有一小點幫助囉~ :)


後記,剛又看了一下你的回文:
目前還在進行觀察中, 但似乎引發錯誤的機率由 100% 已降到 30%以下

我想這也許也是指出indy搞鬼? 因為已經沒死不死的問題,但有咬不咬的問?? :p

===================引 用 RootKit 文 章===================
從本身程式是有主從關係,單僅是 Process Information 提供的 LinkList 。如同 Service Record 一樣。
主從關係主要跟 Token 或權限有關。跟記憶體應無關連性。

個人認為 Indy 發生阻塞的可能性最大。或者在 Timer 中沒有保護好物件。
建議可將該功能先關閉。來查察原因。



------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
編輯記錄
aftcast 重新編輯於 2012-09-25 02:59:07, 註解 無‧
Victor4022
中階會員


發表:0
回覆:76
積分:90
註冊:2011-02-20

發送簡訊給我
#14 引用回覆 回覆 發表時間:2012-09-25 20:33:38 IP:118.161.xxx.xxx 訂閱
1. a.exe 內部是否有使用 array of 的動態陣列? 如有,陣列是否有初始化、在正常陣列大小使用?
=> 曾經碰過 array 宣告 length 為3,但第 [3] 個 index 寫值後,程式隨機跳 access violation,動到後方的程式記憶體位置。
2. a.exe 的 timer 當進入 OnTimer 狀態時,是否會先將 timer.Enabled 設成 false?
=> 曾經接手過一支程式, timer interval 到了之後做的事情超過下一次 interval,結果程式進入兩次,發生不預期錯誤。

3. 程式是否有使用 initialization 與 finalization 進行設計? 如有,請檢查物件生命週期,例如: CriticalSection,在 finalization 進行 DeleteCriticalSection 的時候,很有可能其他 thread 正在 EnterCriticalSection。

以上個人經驗,提供您參考 :)

P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#15 引用回覆 回覆 發表時間:2012-09-25 21:35:12 IP:118.160.xxx.xxx 未訂閱

===================引 用 Victor4022 文 章===================
1. a.exe 內部是否有使用 array of 的動態陣列? 如有,陣列是否有初始化、在正常陣列大小使用?
=> 曾經碰過 array 宣告 length 為3,但第 [3] 個 index 寫值後,程式隨機跳 access violation,動到後方的程式記憶體位置。

3. 程式是否有使用 initialization 與 finalization 進行設計? 如有,請檢查物件生命週期,例如: CriticalSection,在 finalization 進行 DeleteCriticalSection 的時候,很有可能其他 thread 正在 EnterCriticalSection。
沒有
以上個人經驗,提供您參考 :)

P.D.
版主


發表:603
回覆:4038
積分:3874
註冊:2006-10-31

發送簡訊給我
#16 引用回覆 回覆 發表時間:2012-09-27 22:29:17 IP:220.136.xxx.xxx 未訂閱
我把兩支程式併成一支, 目前丟到40台電腦都沒有問題, pas的部份都沒有改, 只是合併起來, 所以看來好像又與indy沒有關係, 不過實在沒有時間去測試拿掉indy 或其他的元件測試, 只好暫時先結案, 感謝各位的鼎力相助, 不知分數給誰, 只要從缺, 抱歉啦!
系統時間:2024-04-27 13:16:22
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!