Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build 39 起 weaselserver.exe 在 Win 7 下有问题 #157

Closed
lifenjoiner opened this issue Mar 26, 2018 · 28 comments
Closed

Build 39 起 weaselserver.exe 在 Win 7 下有问题 #157

lifenjoiner opened this issue Mar 26, 2018 · 28 comments
Assignees

Comments

@lifenjoiner
Copy link

验证过了,win 10 下是没问题;英文 win 7 下有此问题:
16c163a#commitcomment-28230787
issue_master-build-39

DynamicSig[1].Name=OS Version
DynamicSig[1].Value=6.1.7601.2.1.0.256.48
DynamicSig[2].Name=Locale ID
DynamicSig[2].Value=1033

master build 37 也没有问题。
@nameoverflow 并不是在部署,部署是WeaselDeployer.exe啊。

动态调试,一直异常在:
exception_20180326
偏移:

0x1F462 = 128098

定位到死循环:void PipeServer::Listen(ServerHandler const &handler)

pipe = _ConnectServerPipe(pname);

没有多少人跟进测试最新的 build 啊~

@Prcuvu
Copy link
Contributor

Prcuvu commented Mar 26, 2018

我没有 Windows 7,验证需要 @mrhso 的协助。

@nameoverflow
Copy link
Member

???
这个函数当然是死循环啊,listen 不死循环怎么 listen??

@nameoverflow
Copy link
Member

第一次运行本来就会吃 CPU,要么等他载入完要么手动重新部署了再运行

@Prcuvu
Copy link
Contributor

Prcuvu commented Mar 26, 2018

并不是在部署

WeaselServer 有可能会部署。在服务启动时将会执行一次维护,如果检测到需要更新当前文件就会部署。代码在这里:

if (RimeStartMaintenance(/*full_check = */False))
{
m_disabled = true;
}

然后在 librime 中加载部署模块:
https://github.com/rime/librime/blob/6f6056a7b1bcf9053ca6d6e39d2f8e5cb6c8690f/src/rime_api.cc#L99-L120

@lifenjoiner
Copy link
Author

看来,还是不信啊……那调试时一直异常呢?

安装的时候,我是看着的,WeaselDeployer.exe先运行,部署完,WeaselServer启动,要是build 39,CPU 就一直 ›20%;build 37就不会。
再者,手动结束掉进程,手动部署一遍后,再启动WeaselServer,还是一样。

“死循环”嘛,只是个事实,没有任何感情色彩……
我调试到的是一直 try pipe = _ConnectServerPipe(pname); 失败……

我能提供的暂时也就这么多了……不然,就看别人有没有吧。

@lifenjoiner
Copy link
Author

来个比较有力的截图,部署5分钟以上(没有结束),正常吗?
deadloop_1

哎,手*又操作了一次,还得重启电脑……

@nameoverflow
Copy link
Member

nameoverflow commented Mar 26, 2018

既然是 try 失败,需要提供 catch 住的异常号,debugger 都可以看到异常地址。应该是个 DWORD 值。
另外,OS 是否有特殊设置,比如 Windows Server 会有对于文件权限的特殊限制。
在与 NamedPipe 相关的地方有异常,那么是否能够进行输入?

@nameoverflow
Copy link
Member

没有人不信有问题,只是觉得你的表述方式很有意思。

@Guwalgiyakuan
Copy link

我是每个Build都会试,可惜不懂代码没办法提供帮助。有问题也不知道怎么描述比较准确。目前两台win10系统(系统版本一样,一台机一笔记本,安装的Build版本也是相同的)在全新安装阶段有差别,一台无任何问题正常运行安装程序,一台就会先弹出一个未知程序的窗口,点击继续才能开始安装。

@lifenjoiner
Copy link
Author

@nameoverflow
我哪里用词有不当吗?有的话,请指出来,你不说我也不知道……

我反馈都是尽量多地提供自己认为有用、能帮助定位问题的信息。当然,个人水平有限,也不可能完全预先提供你想要的信息。

解释几点:

  1. 为何新开issue?
    两位看了反馈之后,第一反应都是“是在部署”吧……我想其它用户也参与进来,说不定就能快速帮忙找到症结了呢。
  2. 为何写“Build 39 起”?
    之前的,38没有生成安装程序,也没有改程序代码,37正常;39有问题;之后的,最新的build也有这个问题,中间的也试过。
    并不是针对你来挑刺的。程序有问题,有人尽早发现是好事吧。
  3. 你看我最近提的issue比较多,可能会觉得怎么你提交了代码我就来说有问题呢?其实,不是那样的,而是反映了测试用户不够多。
    我们都尊重提交代码的!
    我用的系统也就两个:win10和win7。其它也测试不了。

从版本号来定位,猜测基本就是build 39的代码覆盖的平台不够全面……
现在没有win7,明天有空再试试多了解一下……

@Prcuvu
Copy link
Contributor

Prcuvu commented Mar 26, 2018

我调试到的是一直 try pipe = _ConnectServerPipe(pname); 失败……

从这一段代码(第 316 行开始的死循环):

for (;;) {
HANDLE pipe = INVALID_HANDLE_VALUE;
try {
boost::this_thread::interruption_point();
pipe = _ConnectServerPipe(pname);
boost::thread th([&handler, pipe, this] {
_ProcessPipeThread(pipe, handler);
});
}
catch (DWORD ex) {
_FinalizePipe(pipe);
}
boost::this_thread::interruption_point();
}

定位到这里:
HANDLE PipeChannelBase::_ConnectServerPipe(std::wstring &pn)
{
HANDLE pipe = CreateNamedPipe(
pn.c_str(),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
buff_size,
buff_size,
0,
sa);
if (pipe == INVALID_HANDLE_VALUE || !::ConnectNamedPipe(pipe, NULL)) {
_ThrowLastError;
}
return pipe;
}

这里 _ThrowLastError 来自这个宏定义:
#define _ThrowLastError throw ::GetLastError()

你的截图中有这样一条指令:

00220450	call dword ptr ds:[<&GetLastError>]

我需要你定位到这里,提供 GetLastError() 的返回值。


我一向非常重视能够使用调试器收集更多信息的用户的反馈。我最初的回复是因为当时匆忙瞥了一眼,只解释了是否有部署行为的问题,没有不相信你说存在异常的情况。希望大家收拾好情绪,专注于解决问题。

@lifenjoiner
Copy link
Author

谢谢 @Prcuvu 提示。
我还是很愿意来测试反馈问题的。尽管大家思路不同,求同存异就能做得更好。

看截图:
createnamedpipew_failed
createnamedpipew_failed_errno
err_3e6
对应的代码更改不多:
createnamedpipew_failed_code_reason_1
createnamedpipew_failed_code_reason
个人认为应该是这里了,至于为什么ConvertStringSecurityDescriptorToSecurityDescriptorW没有成功,还要进一步研究……

@lifenjoiner
Copy link
Author

继续……

出错点:
convertstringsecuritydescriptortosecuritydescriptor_failed

channel(std::make_unique<PipeServer>(GetPipeName(), sa.get_attr()))

拿到错误码:
convertstringsecuritydescriptortosecuritydescriptor_failed_errnum
convertstringsecuritydescriptortosecuritydescriptor_failed_errnum_expl

找到代码关键点:

L"S:(ML;;NW;;;LW)D:(A;;FA;;;SY)(A;;FA;;;WD)(A;;FA;;;AC)",

参考:
Security Descriptor String Format
https://msdn.microsoft.com/en-us/library/windows/desktop/aa379570(v=vs.85).aspx

D:dacl_flags(string_ace1)(string_ace2)... (string_acen)
S:sacl_flags(string_ace1)(string_ace2)... (string_acen)

ACE Strings
https://msdn.microsoft.com/en-us/library/windows/desktop/aa374928(v=vs.85).aspx
ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;(resource_attribute)

SID Strings (account_sid)
https://msdn.microsoft.com/en-us/library/windows/desktop/aa379602(v=vs.85).aspx

核实

LW
SY
WD
AC

可知AC是不对的,应该是DC吧?

终于知道,触发这个问题的原因是我这里是域用户,而对应的SID Strings不对。
打了个二进制补丁,通过。

@nameoverflow
Copy link
Member

看来应该设成 WDSDDL_EVERYONE……

@lifenjoiner
Copy link
Author

L"S:(ML;;NW;;;LW)D:(A;;FA;;;SY)(A;;FA;;;WD)(A;;FA;;;AC)",
已经有WD了啊。
AC是不存在的,但是为什么其它情况下不引发错误呢?不了解ConvertStringSecurityDescriptorToSecurityDescriptor的内部机制……

@Prcuvu
Copy link
Contributor

Prcuvu commented Mar 27, 2018

明白了。我们需要在这里做一个版本自适应。

@nameoverflow
Copy link
Member

@Prcuvu 我觉得只是写错了而已(
需要再研究一下 M$ 这个奇怪的 security descriptor。

@Prcuvu Prcuvu closed this as completed in 3d6b1b3 Mar 27, 2018
@Prcuvu
Copy link
Contributor

Prcuvu commented Mar 27, 2018

可知AC是不对的,应该是DC吧?

我觉得只是写错了而已

并没有错,只是那篇文档比较旧了。请参考这篇文档:[MS-DTYP]: Syntax

@Prcuvu
Copy link
Contributor

Prcuvu commented Mar 27, 2018

我在 Windows XP 上测试了一下,依然无法创建 named pipe。

@Prcuvu Prcuvu reopened this Mar 27, 2018
@Prcuvu Prcuvu closed this as completed in b97ccff Mar 27, 2018
@lifenjoiner
Copy link
Author

这个AC确实是版本问题……MS的文档并没有标出来,有点坑!
Win 7 的SDK头文件里没有:
ac_invalid_sdk71

看到 @Prcuvu 已经解决了,很棒!
等明天,确认一下是否“没有DC,有WD,域用户时正常”……

@Prcuvu
Copy link
Contributor

Prcuvu commented Mar 27, 2018

image
Windows 8.1 SDK 就有了。
对比各个版本的 Windows Platform SDK,才能明白不同版本支持哪些设置。

@lifenjoiner
Copy link
Author

确认一下是否“没有DC,有WD,域用户时正常”

正常。

@lotem
Copy link
Member

lotem commented Mar 29, 2018

你们年轻人 不错 有两下子
题 我看不懂 你们谈笑风生

@mrhso
Copy link
Contributor

mrhso commented Mar 29, 2018

已经 解决了 不须 看懂
看不懂 也没关系 还是可以 谈笑风生

@zhaozg
Copy link

zhaozg commented Mar 29, 2018

对各位表示(提问题的 @lifenjoiner 和解决问题的 @Prcuvu and @nameoverflow )表示表示赞👍和感谢😊
另外,我在MacOS, Linux, Windows上都已经用上了Rime,就差Android没有合适的版本了,可有推荐?

@nameoverflow
Copy link
Member

@zhaozg Trime 啊

@zhaozg
Copy link

zhaozg commented Mar 29, 2018

@nameoverflow 同文试过的,版本跟不上Rime的更新

@alexlavigne
Copy link

image
Windows 8.1 SDK 就有了。
对比各个版本的 Windows Platform SDK,才能明白不同版本支持哪些设置。

我现在应该是遇到这个问题了,在win7中,每次重启完电脑后,weasel无法正常使用,输入时直接输出英文,看任务管理器中的进程,没有WeaselServer.exe,此时手动找到weaselServer.exe运行一下,后台多了WeaselServer进程,输入法就正常了。这个问题该怎么解决呢?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants