GetThreadContext函数有错误。。。。

ATMCash4423 2013-08-13 01:11:07


//获取当前进程中所有线程,并存入ThreadInfo
EnumThreadInfo(ThreadInfo);
if (!ThreadInfo.empty())
{
vector<THREADENTRY32>::iterator iter = ThreadInfo.begin();
HANDLE CurrTh = GetCurrentThread();
for (iter = ThreadInfo.begin(); iter != ThreadInfo.end(); iter++)
{
HANDLE th = lpfnOpenThread(THREAD_SUSPEND_RESUME, FALSE, iter->th32ThreadID);
if (th == NULL)
{
ShowError("获取所有线程的句柄时失败!");
}
CONTEXT thtext = {0};
if (th != CurrTh)
{
DWORD err = SuspendThread(th);
if (err == 0xFFFFFFFF)
{
ShowError("挂起线程时失败!");
}
//执行到这句程序崩溃,错误代码为5.
if (GetThreadContext(th, &thtext))
{
IntelStackWalk(&thtext);
}
else
{
ShowError("获取所有线程的信息时失败!");
}
err = ResumeThread(th);
if (err == 0xFFFFFFFF)
{
ShowError("运行挂起的线程时失败!");
}
}
}
}
else
{
_tprintf("未找到任何线程。。。。。。。。");
}




以上是在win7下运行,
在XP下程序直接挂起并不返回了。这是怎么回事啊?为什么GetThreadContext时失败?
...全文
675 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-08-14
  • 打赏
  • 举报
回复
先判断,*iter是否当前线程,或者界面线程,然后再OpenThread 否则当前线程,或者界面线程会挂起。 挂起当前线程,你的这段代码,会挂起。 挂起界面线程,你的界面会死掉。 从NT起,到XP ,对于每个窗口程序,界面线程至少有两个,其中一个是界面线程的守护线程。
ATMCash4423 2013-08-14
  • 打赏
  • 举报
回复
顶,没有人知道吗?
lm_whales 2013-08-14
  • 打赏
  • 举报
回复
其他线程处理界面消息吗???? 不处理界面消息,如何解挂,如果一个挂起的线程,使用锁和其他线程通讯,并且已经获得锁,就会造成和他公用锁的线程死锁。 if (th != CurrTh) 这个是不能排除当前线程的,任何正在运行的线程,都是当前线程。 当前线程句柄,是伪句柄,不是真正的句柄,要获取句柄; 用DuplicateHandle 复制句柄。 而且,你打开线程,在判断之前,没有执行判断,线程就已经挂起了。 PS: 判断界面线程,如果没有做特殊处理,窗口创建的线程就是界面线程,可能有两个,在界面创建和界面第1~n次显示的时候,获当前线程ID和句柄,直到找到两个不同线程为止(句柄值不是0 和-1)。这两个线程不能挂起。
ATMCash4423 2013-08-14
  • 打赏
  • 举报
回复
引用 9 楼 lm_whales 的回复:
先判断,*iter是否当前线程,或者界面线程,然后再OpenThread 否则当前线程,或者界面线程会挂起。 挂起当前线程,你的这段代码,会挂起。 挂起界面线程,你的界面会死掉。 从NT起,到XP ,对于每个窗口程序,界面线程至少有两个,其中一个是界面线程的守护线程。
请问如何判断界面线程?我在openthread之前只有线程的ID,并且上面的程序中已经过滤了当前线程,当前线程不会挂起。就算界面线程被我挂起了,界面死了,但是其他线程还在跑,就会把界面线程解挂啊~~
ATMCash4423 2013-08-13
  • 打赏
  • 举报
回复
我觉得也有可能是权限的问题,我的函数EnumThreadInfo(ThreadInfo); 会获取当前系统下运行的所有进程中的线程,我是通过判断进程ID来分拣出来的,如果微软能这么轻易让其他程序访问其他进程中的线程那不就出问题了。。。。。 我的初衷是想获取本进程中的所有线程,获取线程的CONTEXT信息,我感觉我是绕了一大圈来获取本进程的线程句柄。我贴出获取线程ID的代码(用线程ID并使用openthread来获取线程句柄),看看还有没有其他方式来获取线程句柄(如果能直接获取到线程句柄最好了)。

BOOL EnumThreadInfo(vector<THREADENTRY32> &ThreadInfo)  
{  
	ThreadInfo.clear();
    // 定义线程信息结构   
    THREADENTRY32 te32 = {0} ; 
	te32.dwSize = sizeof(THREADENTRY32);
	
    //创建系统线程快照   
    HANDLE hThreadSnap = CreateToolhelp32Snapshot ( TH32CS_SNAPTHREAD, 0 ) ;  
    if ( hThreadSnap == INVALID_HANDLE_VALUE )  
        return FALSE ;   
	
    // 循环枚举当前进程中的线程信息   
	DWORD dwOwnerPID  = GetCurrentProcessId();
    if ( Thread32First ( hThreadSnap, &te32 ) )  
    {  
        do{  
			if (te32.th32OwnerProcessID == dwOwnerPID)
			{
				ThreadInfo.push_back(te32);
			}
        }while ( Thread32Next ( hThreadSnap, &te32 ) ) ;  
    } 
	else
	{
		CloseHandle ( hThreadSnap ) ;  
		return FALSE;
	}
	
    CloseHandle ( hThreadSnap ) ;  
    return TRUE ;  
}


ATMCash4423 2013-08-13
  • 打赏
  • 举报
回复
引用 5 楼 ml232528 的回复:
lpfnOpenThread是OpenThread函数吧? HANDLE th = lpfnOpenThread(THREAD_SUSPEND_RESUME|THREAD_QUERY_INFORMATION, FALSE, iter->th32ThreadID);
是OpenThread函数。 还是不行,错误代码5.。。。。 我的这段代码在一个异常处理函数中执行的,这个异常函数使用SetUnhandledExceptionFilter函数设置的。我跟过,如果我开了两个线程,在某一个线程崩溃时遍历当前进程中线程还是能找到两个线程的,任务管理器也是在崩溃时显示有两个线程,但就是执行GetThreadContext函数时报错,我本意是想在程序崩溃时保存当前进程中所有线程的堆栈信息。 请再帮我看看还有那地方有问题。。。。郁闷啊。。。。
飞翔的薄荷 2013-08-13
  • 打赏
  • 举报
回复
lpfnOpenThread是OpenThread函数吧? HANDLE th = lpfnOpenThread(THREAD_SUSPEND_RESUME|THREAD_QUERY_INFORMATION, FALSE, iter->th32ThreadID);
ATMCash4423 2013-08-13
  • 打赏
  • 举报
回复
引用 3 楼 ml232528 的回复:
需要权限 THREAD_QUERY_INFORMATION
如何提权?
飞翔的薄荷 2013-08-13
  • 打赏
  • 举报
回复
需要权限 THREAD_QUERY_INFORMATION
ATMCash4423 2013-08-13
  • 打赏
  • 举报
回复
引用 1 楼 zgl7903 的回复:
GetThreadContext 之前 试试 thtext.ContextFlags = CONTEXT_CONTROL;
没有变化,GetThreadContext依然失败,错误代码5
zgl7903 2013-08-13
  • 打赏
  • 举报
回复
GetThreadContext 之前 试试 thtext.ContextFlags = CONTEXT_CONTROL;

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧