最近使用electron做了一个app,支持windows和mac,然后总是莫名其妙的crash,使用crashReporter提交的报告根本搞不明白。错误如下:
24520:1217/182314.561309:FATAL:partition_alloc.cc(934)] Check failed: page->num_allocated_slots != -1.
这里只截取了错误信息的第一行,crashReporter获得的信息截取如下:
Thread 21 (crashed)
0 Electron Framework + 0x208cf1
rbx = 0x0000000000000000 r12 = 0x000070000a0c33b0
r13 = 0x000070000a0c3890 r14 = 0x000070000a0c3880
r15 = 0x000070000a0c3888 rip = 0x0000000109de1cf1
rsp = 0x000070000a0c3380 rbp = 0x000070000a0c3380
Found by: given as instruction pointer in context
1 Electron Framework + 0x23f28d
rip = 0x0000000109e1828d rsp = 0x000070000a0c3390
rbp = 0x000070000a0c3870
Found by: stack scanning
由于看不明白,各种在electron上面找issue,然后发现,bug里面有人说renderer进程里面使用request会导致崩溃,由于是bug,根本是死局啊,抱着将信将疑的态度,进行了修改。
request是要用的,那么只能从renderer进程里面移出来了,解决方案如下:
使用nodejs的子进程fork功能,创建一个子进程,使用process.on监听父进程的请求,在renderer进程里面使用向子进程发送请求,由子进程处理request请求并返回给父进程。
在renderer里面的代码如下:
let jsProcess = require('child_process').fork(__dirname +'/executor.js', ['http://localhost'],{ silent: false})
//处理post请求
//success是成功的回调函数,failed是出错的回调函数
function post(url, reqBody, success, failed){
jsProcess.send({url: url, body: reqBody})
jsProcess.once('message', (message)=>{
if(message.error || message.code != 200){
failed(message.error, message.code);
}else{
let result = message.result
success(result);
}
})
}
executor.js里面的代码如下:
let baseUrl = ''
function handle(){
if(process.argv.length < 3){
throw new Error('System Error: Parameters length error.');
}
baseUrl = process.argv[2]
//使用process监听主进程请求
process.on('message', function(message){
try {
//其中post函数主要使用request发送请求返回结果,这里就不贴代码了
//我使用了system-sleep将异步改写成了同步,所以可以这样直接调用
//res包括错误信息和结果{error,result,code}
let res = post(message.url, message.body);
process.send(res);
} catch (error) {
console.log(error)
}
})
}
handle();
大概描述了一下解决思路,代码不全,当然解决方案也可能存在我不知道的问题,暂且记录一下,以后如果electron bug改了,说不定就不需要这么处理了。也可能我的处理方案并不好,不过对于c++没有研究,想不出更好的方法了,如果大家有好方法,欢迎分享啊。
ps:目前,app已经不像以前那么容易崩溃了,至少我测试的时候没发现再次崩溃的情况 ,以后如果再崩溃的话,恩,我说不定还得再想办法。