[√]window下子线程CCLOG导致主线程阻塞问题

简介: [√]window下子线程CCLOG导致主线程阻塞问题

windbg wdk下载

下载地址,安装的时候选择Debugging Tools For Windows即可

image.png

windbg 使用

通过File/Attach to a process快捷键F6附加到已经阻塞的程序中

查看所有线程的堆栈信息

~*kb

  • k*  命令显示给定线程的堆栈帧以及相关信息。
  • b选项显示传递给堆栈跟踪中每个函数的前三个参数。

image.png

vs的线程情况

可以看到在这里加锁时,因为被其他线程锁定了,其他线程并没有解锁,就导致这里被阻塞了

image.png

f

!cs -l 仅显示死锁的临界区信息。

相关的的线程锁函数

NtWaitForAlertByThreadId

NtWaitForAlertByThreadId 是在 Windows 操作系统中的 ntdll.dll 动态链接库中定义的函数,用于等待指定线程的警告状态。

该函数的原型如下:

cCopy Code
NTSTATUS NtWaitForAlertByThreadId(
  HANDLE     ThreadHandle,
  PLARGE_INTEGER Timeout
);
  • ThreadHandle:要等待的线程句柄。
  • Timeout:等待的超时时间。

该函数的作用是使当前线程进入等待状态,直到所指定的线程发出警告通知。警告通常由应用程序自定义的机制触发。

出现在调用堆栈中的 NtWaitForAlertByThreadId 表明当前线程正在等待指定线程发出的警告。

WaitForMultipleObjects

DWORD WaitForMultipleObjects(
  [in] DWORD        nCount,
  [in] const HANDLE *lpHandles,
  [in] BOOL         bWaitAll,
  [in] DWORD        dwMilliseconds
);
2  Id: 2568.4a78 Suspend: 1 Teb: 01bcc000 Unfrozen
#  ChildEBP RetAddr  Args to Child              
00 05cffcf4 75b13033 00000003 05830bf0  00000001 ntdll!NtWaitForMultipleObjects+0xc
                     nCount   lpHandles bWaitAll # 对应的参数
# 第二个参数是个指针,通过dd查看指针指向的内存数据
:003> dd 05830bf0 
05830bf0  00000510 00000518 0000051c 00000000
05830c00  05830c30 00000000 00000000 00000000
05830c10  00000000 00000000 00000000 00000000
05830c20  00000000 00000000 00000000 00000000
05830c30  05830c60 00000000 00000000 00000000
05830c40  00000000 00000000 00000000 00000000
05830c50  00000000 00000000 00000000 00000000
05830c60  05830c90 00000000 00000000 00000000
0:003> !cs 05830bf0 
-----------------------------------------
Critical section   = 0x05830bf0 (+0x5830BF0)
DebugInfo          = 0x00000510
LOCKED
LockCount          = 0xFFFFFEB9  # 这是一个负数
WaiterWoken        = Yes
OwningThread       = 0x00000000 # 没有线程拥有它
RecursionCount     = 0x51C
LockSemaphore      = 0x5830C30
SpinCount          = 0x00000000

WaitForSingleObject

DWORD WaitForSingleObject(
  [in] HANDLE hHandle,
  [in] DWORD  dwMilliseconds
);

最终问题定位

程序就是出现了死锁,死锁的原因是window窗口部分代码导致的,子线程调用Windows的SendMessage,导致的主线程阻塞,网上说SendMessage里面其实有一个锁,有这种可能导致主线程阻塞。

CCLOG函数在win32上的实现,里面有调用SendMessage,而我在子线程里面打log,触发了这个大坑

解决办法是MsgWaitForMultipleObjects(),但是我不清楚怎么处理,对Windows编程不太熟悉,这也算是cocos2dx的一个bug

目录
相关文章
|
6月前
|
安全 Java
【JavaSE专栏76】三态和五态,线程的不同状态:新建、运行、状态、阻塞、等待、计时等待状态
【JavaSE专栏76】三态和五态,线程的不同状态:新建、运行、状态、阻塞、等待、计时等待状态
|
7月前
|
Arthas IDE Java
一种获取阻塞线程栈帧数据的思路
一种获取阻塞线程栈帧数据的思路
125 1
|
1月前
|
消息中间件 Linux 调度
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
73 0
|
7天前
|
监控
写一个线程来监控各线程是否发生阻塞
写一个线程来监控各线程是否发生阻塞
17 0
|
7月前
|
Arthas 测试技术
如何检测由synchronized或Lock引起的线程阻塞问题
如何检测由synchronized或Lock引起的线程阻塞问题
110 0
|
7月前
|
Arthas 消息中间件 监控
记一次SSL握手导致业务线程阻塞的案例分析
记一次SSL握手导致业务线程阻塞的案例分析
108 0
|
9月前
|
缓存 运维 监控
SSL Session默认设置导致线程阻塞了几十秒的案例分析
SSL Session默认设置导致线程阻塞了几十秒的案例分析
113 0
|
9月前
线程阻塞问题
CompletableFuture.supplyAsync()执行线程,任务内有sleep方法休眠等待。导致主线程阻塞。
41 0
|
6月前
|
Java 数据库
【JavaSE专栏79】线程死锁,多个线程被阻塞,等待彼此持有的资源
【JavaSE专栏79】线程死锁,多个线程被阻塞,等待彼此持有的资源
|
6月前
|
Java 开发者
停止线程 & 守护线程 & 线程阻塞
停止线程 & 守护线程 & 线程阻塞
9 0
停止线程 & 守护线程 & 线程阻塞