Skia下SK_DEBUG内联的坑
以下代码可能出现看起来诡异的错误
{
auto data = image->encodeToData();
std::stringstream ss;
ss << count++ << "_output.png";
if (data) {
SkFILEWStream out(ss.str().c_str());
out.write(data->writable_data(), data->size());
}
}
错误如下:
* thread #3, name = 'RasterThread', stop reason = signal SIGILL: illegal operand
* frame #0: 0x000000000c02edd4 Sxxxx`sk_abort_no_print() at SkMemory_malloc.cpp:51:5
frame #1: 0x000000000bbbee39 Sxxxx`SkNVRefCnt<SkData>::~SkNVRefCnt(this=0x00007fffafdff530)::'lambda'()::operator()() const at SkRefCnt.h:165:9
frame #2: 0x000000000bbbec35 Sxxxx`SkNVRefCnt<SkData>::~SkNVRefCnt(this=0x00007fffa8006090) at SkRefCnt.h:165:9
frame #3: 0x000000000bbbd8ba Sxxxx`SkData::~SkData(this=0x00007fffa8006090) at SkData.cpp:37:1
具体是因为这个ASSERT:
~SkNVRefCnt() {
#ifdef SK_DEBUG
int rc = fRefCnt.load(std::memory_order_relaxed);
SkASSERTF(rc == 1, "NVRefCnt was %d", rc);
#endif
}
我们的工程是使用include + .a库
集成的,工程并没有设置SK_DEBUG
,按理这个逻辑不应该触发…..
Debug时,发现有以下信息:
(lldb) s
Process 5195 stopped
* thread #3, name = 'RasterThread', stop reason = step in
frame #0: 0x0000000009383401 Sxxxx`WebCore::xxxxxx [inlined] SkNVRefCnt<SkData>::unref(this=0x00007fffa8006090) const at SkRefCnt.h:180:13
(lldb) p fRefCnt
(std::atomic<int>) {
std::__atomic_base<int> = (_M_i = 0)
}
(lldb) s
Process 5195 stopped
* thread #3, name = 'RasterThread', stop reason = step in
frame #0: 0x000000000bbbd8b4 Sxxxx`SkData::~SkData(this=0x00007fffa8006090) at SkData.cpp:34:9
(lldb)
注意SkData的定义:
class SK_API SkData final : public SkNVRefCnt<SkData> {
....
.a库是Debug库,但看起来SkData::~SkData
内联了SkNVRefCnt
的析构….真是及不胜防。
相关头文件如下图:
按照这个原因,打开skia/include/config/SkUserConfig.h的SK_DEBUG
,果然Crash没有了。