Multithreading – is Delphi 2009 wait chain traversal provided in Windows 7 installation?
According to the "new features of Delphi 2009", there is a new debugger function called "waiting chain traversal" In particular, it said: "a waiting chain traversal function has been added to help you solve thread contention or deadlock problems. This function depends on the tools added to the Windows Vista operating system. It provides the debugger with information about the waiting state of application threads in the form of waiting chain"
Delphi 2009 was released when Windows vista was the current operating system From my experience, most of the features introduced in Vista can also be used in Windows 7 However, in Delphi 2009, I saw this function through Delphi Xe installation (none on Windows 7)
I'm looking for this feature in the threads pane of the debugger
I'm looking for the right place to wait for chain traversal? > Is it a feature that is really only available in Windows Vista, not in Windows 7?
David M provides a good and clear answer, but I still don't get the "waiting chain" column in the threads pane Here are some codes
Main forms:
unit Main; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls,SyncObjs,RanThread; type TForm1 = class(TForm) List@R_460_2419@1: TList@R_460_2419@; Button1: TButton; Button2: TButton; Label1: TLabel; procedure Button2Click(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure ThreadDone(Sender: TObject); end; var Form1: TForm1; RanGenThread: TRandomizer; implementation uses LoadThread; {$R *.dfm} { TForm1 } procedure TForm1.ThreadDone(Sender: TObject); begin RanGenThread.Free; end; procedure TForm1.Button2Click(Sender: TObject); begin List@R_460_2419@1.sorted := True; end; procedure TForm1.Button1Click(Sender: TObject); var Thread: TLoader; begin List@R_460_2419@1.Items.Clear; List@R_460_2419@1.sorted := False; RanGenThread := TRandomizer.Create(True); RanGenThread.ArraySize := 1000; Thread := TLoader.Create(True); with Thread do begin RanGenThread.WaitThread := Thread; FreeOnTerminate := True; OnTerminate := ThreadDone; WaitForThread := RanGenThread; //Use Start in Delphi 2010 or later,where Resume is deprecated Resume; end; RanGenThread.Resume; end; initialization Randomize; end.
TRandomizer:
unit RanThread; interface uses Classes,Math,SyncObjs; type TRandomizer = class(TThread) private { Private declarations } FArraySize: Integer; protected procedure Execute; override; public WaitThread: TThread; RandNumbers: array of Integer; property ArraySize: Integer read FArraySize write FArraySize; end; implementation uses Main; procedure TRandomizer.Execute; var i: Integer; LowNum,HighNum: Integer; RandNum: Integer; begin if FArraySize = 0 then begin Exit; end; SetLength(RandNumbers,FArraySize); LowNum := Low(RandNumbers); HighNum := High(RandNumbers); //initialize the array for i := LowNum to HighNum do RandNumbers[i] := -1; // generate the random order for i := LowNum to HighNum do while True do begin RandNum := RandomRange(LowNum,HighNum + 1); if RandNumbers[RandNum] = -1 then begin RandNumbers[RandNum] := i + 1; break; end; // if end; // while WaitThread.WaitFor; end; end.
TLoader:
unit LoadThread; interface uses Classes,RanThread; type TLoader = class(TThread) private FWaitForThread: TRandomizer; procedure UpdateList; { Private declarations } protected procedure Execute; override; public property WaitForThread: TRandomizer read FWaitForThread write FWaitForThread; end; implementation uses Main; procedure TLoader.UpdateList; var i: Integer; begin for i := Low(FWaitForThread.RandNumbers) to High(FWaitForThread.RandNumbers) do Form1.List@R_460_2419@1.Items.Add(IntToStr(FWaitForThread.RandNumbers[i])); end; procedure TLoader.Execute; begin if WaitForThread <> nil then begin FWaitForThread.WaitFor; Synchronize(UpDateList) end; end; end.
According to the waiting chain traversal document linked by David M, WTC can be used for the following synchronization objects:
>Alpc > com > key parts > mutual exclusion > SendMessage > waiting for operations on processes and threads
My code waits for a thread, but it is a TThread, not a direct native thread Tonight, I'll modify my code example to deadlock while waiting for a mutex to see if it causes the "wait chain" column to appear in the threads pane
OK Finally, find time for the next test Create an application that occupies a mutex at startup Create a handle that uses OpenMutex to get the Mutex and then call the WaitForsingleObject (handle, INFINITE) worker thread. There is still no waiting chain column in the threads pane
Solution
>Yes Write a program with two thread deadlocks You will see that in the threads pane, the right column (labeled wait chain) displays "waiting for locks held by thread 12345" I'm not quite sure about the exact phrase because there is no deadlock in my current program:) if you don't see it, scroll to the right It's strange if the column doesn't exist - please say it in the comments
Editor: I tried the sample code in Delphi 2010 on Vista machine (I'm not afraid of 2009) I clicked button1 and button2, and then switched to the threads view without pausing the program In the threads pane, there is a waiting chain column that contains the text of two non main threads "blocked waiting threads 11968" or "14416"
This is a screenshot:
If this function works, then this is what you should get in the IDE
When you try this, you get other columns, but not waiting for chain columns? If so, I admit I'm a little confused. I think the next step may be to contact Embarcadero or at least publish it in one of their forums, probably this one I found out what permissions the wait chain function requires, but if you are using a process owned by the current user, you seem to be don't even need se_ DEBUG_ NAME. (I'm not entirely sure this is a valid interpretation of the document, but...)
I don't think your ide runs in odd privilege or XP compatible mode? Editor 4: This is the answer Please refer to Cary's comments below. The shortcut runs in XP compatible mode
Editor 2: I thought I would do a sanity check and look up what their help file said I can't find help online in 2009, but the help in 2010 says "wait chain: (for Windows Vista and 7 only)" Cool Then I looked at the help of Xe and said 'wait chain: (for Windows Vista only)' Very strange.
I suspect this is a document error. It should work on Windows 7, because I also encountered this Delphi 2009 hotfix for wait chain traversal running on Windows 7 Sounds very supportive of me! There is no way to be sure that this feature will be removed from the latest version of windows... Right? Even if they use a version, it is recorded
Editor 3: I asked my colleagues using Windows 7 to try your sample code This is what he got:
On this point, I admit I'm a little confused I can say that the works using rad studio 2010 on Windows 7, as far as I know, should be suitable for you If not, I don't have more suggestions beyond the above vague ideas!