CreateProcess 创建进程失败原因调查

在特定Windows系统中,使用CreateProcess创建进程时遇到ERROR_ACCESS_DENIED(0x05)错误。通过分析发现,问题出在CREATE_BREAKAWAY_FROM_JOB标志上。若无必要,移除此标志可解决问题。当需要该特性时,需确保Job对象具有JOB_OBJECT_LIMIT_BREAKAWAY_OK属性。遇到类似情况,检查CREATE_BREAKAWAY_FROM_JOB可能是关键。

使用 CreateProcess 函数创建进程(调用外部程序)算是很常用的操作了,最近在工作中却遇到一个少见的怪现象,经常使用的一段代码(调用外部程序并等待其结束,主要就使用了 CreateProcess 函数),在少数某些机器上会失败(目前只在某一个 Win8.1 和某一个 Win10 机器遭遇失败)。

经调查分析,发现正是 CreateProcess 调用失败,GetLastError 返回 0x05 错误(ERROR_ACCESS_DENIED),凭经验知道这是权限不足的问题,但具体是什么原因?一时无解。继续排查,发现原先有另一处调用外部程序的代码是不存在该问题的,仔细对比两处代码,发现调用 CreateProcess 时的第6个参数(dwCreationFlags)不一样!问题代码中使用了 CREATE_BREAKAWAY_FROM_JOB 值(和 Job Object 有关),马上去掉该值再测试,问题果然没有了!

抱着「知其然,还要知其所以然。」的一惯态度,继续寻找导致该问题的原因,历程如下:

1. 先是深入解读了 MSDN 相关部分,了解到使用 CREATE_BREAKAWAY_FROM_JOB 参数是需要前提条件的:需要其关联的 Job 对象具有 JOB_OBJECT_LIMIT_BREAKAWAY_OK 属性,否则就会失败,但 MSDN 中并未明确指出失败码为 0x05。

2. 网上求解过程中,意外地在 Chrome Issues 列表中发现同样的问题:「WinAPI  CreateProcessAsUserW() with CREATE_BREAKAWAY_FROM_JOB flag which fails with 0x5 (access denied) error.」。

3. 翻书《Windows核心编程》也找到了对 CREATE_BREAKAWAY_FROM_JOB 的相关说明(如下图):

总结一下:
我使用的这段代码是从以前的工程里拷贝来的,至于为什么带上了 CREATE_BREAKAWAY_FROM_JOB 参数,属于历史问题就不得而知了,这个参数的目的是让子进程脱离父进程的 Job,如果本没有这个需求的话,可以不用考虑直接去掉,如果确实需要该特性的话,那就得按官方的要求来,要确保其 Job 对象具有 JOB_OBJECT_LIMIT_BREAKAWAY_OK 属性(具体怎么实现不属于本文的范畴了)。个别机器上可能由于系统环境的某些特殊原因,造成相关 Job 对象不具有 JOB_OBJECT_LIMIT_BREAKAWAY_OK 属性,因此导致了该问题的出现,图证如下:

有Breakaway OK属性
vs
无Breakaway OK属性

所以,以后遇到 CreateProcess 失败,错误码为 0x05 时,去检查一下参数里是否有 CREATE_BREAKAWAY_FROM_JOB 吧!


参考:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684161(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684147(v=vs.85).aspx
https://code.google.com/p/chromium/issues/detail?id=79091#c45
《Windows核心编程》


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值