summaryrefslogtreecommitdiffstatsabout
path: root/SylixOS
diff options
context:
space:
mode:
authorHanhui <hanhui@acoinfo.com>2020-09-24 08:45:28 (GMT)
committer Hanhui <hanhui@acoinfo.com>2020-09-24 08:45:28 (GMT)
commit2aff4fd5086d4cad4d23bc9be22e6ce77402d84a (patch)
treee4854cf3d228ee8beb089a4d59e362c6ed05eccf /SylixOS
parent2d910c188501c42c927dfd90efd0843a5ff6497b (diff)
downloadlibsylixos-2aff4fd5086d4cad4d23bc9be22e6ce77402d84a.zip
libsylixos-2aff4fd5086d4cad4d23bc9be22e6ce77402d84a.tar.gz
libsylixos-2aff4fd5086d4cad4d23bc9be22e6ce77402d84a.tar.bz2
Fixed loader lock deadlock.
Diffstat (limited to 'SylixOS')
-rw-r--r--SylixOS/loader/elf/elf_loader.c1
-rw-r--r--SylixOS/loader/include/loader_lib.h2
-rw-r--r--SylixOS/loader/src/loader.c33
3 files changed, 32 insertions, 4 deletions
diff --git a/SylixOS/loader/elf/elf_loader.c b/SylixOS/loader/elf/elf_loader.c
index 104fb29..632ddf3 100644
--- a/SylixOS/loader/elf/elf_loader.c
+++ b/SylixOS/loader/elf/elf_loader.c
@@ -2051,6 +2051,7 @@ INT __elfListLoad (LW_LD_EXEC_MODULE *pmodule, CPCHAR pcPath)
goto __out;
}
pmodTemp->EMOD_ulStatus = LW_LD_STATUS_LOADED;
+ pmodTemp->EMOD_pvRoot = pmodule;
}
pringTemp = _list_ring_get_next(pringTemp);
} while (pringTemp != &pmodule->EMOD_ringModules);
diff --git a/SylixOS/loader/include/loader_lib.h b/SylixOS/loader/include/loader_lib.h
index 06b557b..16ca16a 100644
--- a/SylixOS/loader/include/loader_lib.h
+++ b/SylixOS/loader/include/loader_lib.h
@@ -158,6 +158,8 @@ typedef struct {
dev_t EMOD_dev; /* 模块文件设备标识 */
ino_t EMOD_ino; /* 模块文件 inode 标识 */
+ PVOID EMOD_pvRoot; /* 导致模块被加载或卸载根模块 */
+
#if LW_CFG_MODULELOADER_TEXT_RO_EN > 0
size_t EMOD_stCodeLen; /* 模块代码段长度 */
ULONG EMOD_ulCodeOft; /* 模块代码段偏移 */
diff --git a/SylixOS/loader/src/loader.c b/SylixOS/loader/src/loader.c
index 211f4c0..2747c39 100644
--- a/SylixOS/loader/src/loader.c
+++ b/SylixOS/loader/src/loader.c
@@ -178,6 +178,7 @@ static LW_LD_EXEC_MODULE *moduleCreate (CPCHAR pcPath,
pmodule->EMOD_dev = pstatFile->st_dev;
pmodule->EMOD_ino = pstatFile->st_ino;
pmodule->EMOD_pvproc = (LW_LD_VPROC *)pvVProc;
+ pmodule->EMOD_pvRoot = LW_NULL;
if (pcInit) {
pmodule->EMOD_pcInit = (PCHAR)pmodule + stInitOff;
@@ -476,8 +477,17 @@ static INT initArrayCall (LW_LD_EXEC_MODULE *pmodule)
do {
pmodTemp = _LIST_ENTRY(pringTemp, LW_LD_EXEC_MODULE, EMOD_ringModules);
- if (pmodTemp->EMOD_ulStatus == LW_LD_STATUS_LOADED) {
+ if (pmodTemp->EMOD_ulStatus == LW_LD_STATUS_LOADED && pmodTemp->EMOD_pvRoot == pmodule) {
pmodTemp->EMOD_ulStatus = LW_LD_STATUS_INITED; /* 处理构造函数调用opendl */
+ /*
+ * 这里必须释放锁,因为初始化函数可能调用到加锁的代码如dlopen,如果不释放可能导致死锁。
+ * 这里释放锁没有问题,因为:
+ * 1、模块状态已经在加锁时修改了,其它线程不会重复进入初始化函数。
+ * 2、本模块不会被卸载,因为模块句柄尚未返回。
+ * 3、进程模块链表可能会新增其它模块,但不会影响本模块,链表改动和读取都处于加锁状态,所以不会错乱
+ * 4、如果进程在解锁状态被kill掉,则执行初始化函数的线程停止,不会异常,同时也不会占用锁
+ */
+ LW_VP_UNLOCK(pmodule->EMOD_pvproc);
for (i = 0; i < pmodTemp->EMOD_ulInitArrCnt; i++) { /* 正顺序调用初始化函数 */
pfuncInit = pmodTemp->EMOD_ppfuncInitArray[i];
@@ -492,7 +502,6 @@ static INT initArrayCall (LW_LD_EXEC_MODULE *pmodule)
iRet = pmodTemp->EMOD_pfuncInit();
if (pmodTemp->EMOD_ulModType == LW_LD_MOD_TYPE_KO) { /* 内核模块需要判断返回值 */
if (iRet < 0) {
- LW_VP_UNLOCK(pmodule->EMOD_pvproc);
return (PX_ERROR);
} else if (iRet == LW_INIT_RET_UNLOAD_DISALLOW) {
@@ -500,10 +509,11 @@ static INT initArrayCall (LW_LD_EXEC_MODULE *pmodule)
}
}
}
-
+
#if LW_CFG_TRUSTED_COMPUTING_EN > 0
bspTrustedModuleLoad((PVOID)pmodTemp);
#endif /* LW_CFG_TRUSTED_COMPUTING_EN */
+ LW_VP_LOCK(pmodule->EMOD_pvproc);
}
pringTemp = _list_ring_get_prev(pringTemp);
@@ -623,8 +633,14 @@ static INT finiArrayCall (LW_LD_EXEC_MODULE *pmodule, BOOL bRunFini)
do {
pmodTemp = _LIST_ENTRY(pringTemp, LW_LD_EXEC_MODULE, EMOD_ringModules);
- if (pmodTemp->EMOD_ulRefs == 0 && pmodTemp->EMOD_ulStatus == LW_LD_STATUS_INITED) {
+ if (pmodTemp->EMOD_ulRefs == 0 &&
+ pmodTemp->EMOD_ulStatus == LW_LD_STATUS_INITED &&
+ pmodTemp->EMOD_pvRoot == pmodule) {
pmodTemp->EMOD_ulStatus = LW_LD_STATUS_FINIED;
+ /*
+ * 原因参考initArrayCall函数
+ */
+ LW_VP_UNLOCK(pmodule->EMOD_pvproc);
if (pmodTemp->EMOD_ulModType == LW_LD_MOD_TYPE_KO) { /* 处理内核模块 atexit */
LW_LD_EXEC_MODATEXIT *pmodae;
@@ -683,6 +699,8 @@ static INT finiArrayCall (LW_LD_EXEC_MODULE *pmodule, BOOL bRunFini)
__cxa_module_finalize(pmodTemp->EMOD_pvBaseAddr,
pmodTemp->EMOD_stLen,
bRunFini); /* 释放当前模块的 cxx_atexit */
+
+ LW_VP_LOCK(pmodule->EMOD_pvproc);
}
pringTemp = _list_ring_get_next(pringTemp);
@@ -709,6 +727,7 @@ static INT moduleCleanup (LW_LD_EXEC_MODULE *pmodule)
pmodTemp = _LIST_ENTRY(pringTemp, LW_LD_EXEC_MODULE, EMOD_ringModules);
pmodTemp->EMOD_ulRefs = 0;
+ pmodTemp->EMOD_pvRoot = pmodule;
pringTemp = _list_ring_get_next(pringTemp);
} while (pringTemp != &pmodule->EMOD_ringModules);
@@ -735,6 +754,9 @@ static INT moduleDelRef (LW_LD_EXEC_MODULE *pmodule)
LW_VP_LOCK(pmodule->EMOD_pvproc);
if (pmodule->EMOD_ulRefs > 0) {
pmodule->EMOD_ulRefs--;
+ if (pmodule->EMOD_ulRefs == 0) {
+ pmodule->EMOD_pvRoot = pmodule;
+ }
}
while (bUpdated) {
@@ -748,6 +770,9 @@ static INT moduleDelRef (LW_LD_EXEC_MODULE *pmodule)
for (i = 0; i < pmodTemp->EMOD_ulUsedCnt; i++) {
if (pmodUsedArr[i] && pmodUsedArr[i]->EMOD_ulRefs > 0) {
pmodUsedArr[i]->EMOD_ulRefs--;
+ if (pmodUsedArr[i]->EMOD_ulRefs == 0) {
+ pmodUsedArr[i]->EMOD_pvRoot = pmodule;
+ }
bUpdated = LW_TRUE;
}
}