성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <br /> <div style='font-family: 맑은 고딕, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>보호 모드로 응용 프로그램 디버깅하는 방법 - 두 번째 이야기</div><br /> <br /> 지난 이야기에서, <br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > 보호 모드로 응용 프로그램 디버깅하는 방법 ; <a target='_tab' href='/2/0/682'>http://www.sysnet.pe.kr/2/0/682</a> </pre> <br /> 보호 모드로 디버깅하는 방법을 다뤄봤는데요. 좀 사용하다 보면 불편한 점이 있습니다. 예를 들어, 이미 빌드된 프로젝트를 디버깅하는 경우라면 "100ms * 50"의 시간 내에 디버깅이 되겠지만, 새로 빌드되는 경우라면 가뿐히 그 시간을 넘어버립니다. 게다가 100ms 마다 모든 프로세스를 열람해서 이름 비교하게 하는 것에 CPU 자원을 소모하는 것도 아깝지요. 이 때문에 빌드 시간을 고려해서 그 만큼 쓰레드의 루프를 늘리는 것도 부담됩니다.<br /> <br /> 이런 불편을 해소하기 위해서, 다음과 같은 방법을 적용해 보면 좋겠다는 생각이 듭니다.<br /> <br /> <ol> <li>신규 프로세스를 감시</li> <li>신규 프로세스의 부모 프로세스가 디버깅 대상 프로세스인 경우에만 Debug.Attach</li> </ol> <br /> 자... 그럼 해볼까요? ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 첫 번째 항목을 해결하기 위해서 검색을 해보면 몇 가지 좋은 방법이 눈에 띕니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Detecting Windows NT/2K process execution By Ivo Ivanov ; <a target='_tab' href='http://www.codeproject.com/KB/threads/procmon.aspx'>http://www.codeproject.com/KB/threads/procmon.aspx</a> Process Information and Notifications using WMI By Asghar Panahy ; <a target='_tab' href='http://www.codeproject.com/KB/system/win32processusingwmi.aspx'>http://www.codeproject.com/KB/system/win32processusingwmi.aspx</a> </pre> <br /> 정확한 방법을 선택한다면 "Ivo Ivanov"가 제안한 방법이 훌륭하겠지만 VS.NET 매크로에 적용하기 위해서는 "Asghar Panahy"가 제안한 방법이 더 훌륭합니다.<br /> <br /> 그렇게 해서 WMI를 이용하여 프로세스를 감시하겠다고 했으면, 두 번째 항목도 자연스럽게 해결됩니다. WMI 이벤트 발생 시점에 디버깅 대상의 프로세스 ID와 2차 생성된 프로세스의 부모 프로세스 ID를 비교하여 Process.Attach 메서드를 실행시키면 되기 때문입니다.<br /> <br /> 그래서 VB 매크로로 적용해 보면 아래와 같습니다. (소스는 복잡해졌지만 대상 프로세스 명도 지정할 필요없으니, 적용하기에는 더욱 편해졌습니다.)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Public Module DTEHelper Public Sub RunAndAttachTo() DTE.Solution.SolutionBuild.Build(True) DTE.Solution.SolutionBuild.Debug() AttachTo() End Sub Dim watcher As ManagementEventWatcher Public Sub AttachTo() Dim pol As String pol = "1" Dim queryString As String <b style='color: Blue;'>queryString = "SELECT *" & _ " FROM __InstanceOperationEvent " & _ "WITHIN " & pol & _ " WHERE TargetInstance ISA 'Win32_Process'"</b> Dim scope As String scope = "\\.\root\CIMV2" If (watcher Is Nothing) Then Else watcher.Stop() watcher = Nothing End If watcher = New ManagementEventWatcher(scope, queryString) Debug.Print(queryString) ' 새로 생성되는 프로세스를 감시한다. AddHandler watcher.EventArrived, AddressOf OnEventArrived watcher.Start() End Sub Private Sub OnEventArrived(ByVal sender As Object, _ ByVal e As EventArrivedEventArgs) Dim watcher As ManagementEventWatcher watcher = sender If (DTE.Debugger.DebuggedProcesses.Count = 0) Then watcher.Stop() Exit Sub End If Dim debuggeeProcessId As Integer Dim processes As EnvDTE.Processes processes = DTE.Debugger.DebuggedProcesses ' 1차 디버깅 프로세스의 ID를 구한다. ' 즉 psexec.exe의 ID를 구한다. <b style='color: Blue;'>If (processes.Count <> 0) Then For Each proc As EnvDTE.Process In processes debuggeeProcessId = proc.ProcessID Next End If</b> ' 새로 생성된 프로세스의 부모 프로세스 ID를 구한다. ' 즉 psexec.exe의 하위에 생성된 프로세스를 구별해 낸다. Dim parentProcessIdOfnewProcess As Integer Dim targetInstance As ManagementBaseObject targetInstance = e.NewEvent.Properties("TargetInstance").Value <b style='color: Blue;'>parentProcessIdOfnewProcess = targetInstance.Properties("ParentProcessId").Value</b> ' 만약 psexec.exe의 하위 프로세스라면 디버거를 연결한다. If (parentProcessIdOfnewProcess = debuggeeProcessId) Then Dim newProcessName As String newProcessName = targetInstance.Properties("Name").Value.ToString() watcher.Stop() For Each proc In DTE.Debugger.LocalProcesses If (proc.Name.IndexOf(newProcessName) <> -1) Then Debug.Print("Attached successfully!") <b style='color: Blue;'>proc.Attach()</b> Exit For End If Next End If End Sub End Module </pre> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1906
(왼쪽의 숫자를 입력해야 합니다.)