• 5213阅读
  • 2回复

[提问]用vs2012 x86编译的Qt5,assistant无法启动? [复制链接]

上一主题 下一主题
离线lyh_blank
 
只看楼主 倒序阅读 楼主  发表于: 2012-12-28
我使用vs2010 x86/x64、vs2012 x86/x64四种工具链分别编译Qt5,唯有vs2012 x86的生成结果有这个问题,很奇怪。
使用vs2012直接打开assistant.exe,并启动调试,能够从堆栈信息中得知异常可能是发生在Qt5Webkit模块内,于是直接编译一个调试版本的assistant,想查个究竟,可这个居然是正常的。
不知道大家有没有遇到这个问题?
离线lyh_blank
只看该作者 1楼 发表于: 2012-12-28
被这种莫名其妙的问题卡住,很不爽,索性编了一套带调试信息的Release版,调试后,发现问题是出在文件TextEncodingRegistry.cpp中(Qt5Webkit模块):
PassOwnPtr<TextCodec> newTextCodec(const TextEncoding& encoding)
{
    MutexLocker lock(encodingRegistryMutex());

    ASSERT(textCodecMap);
    TextCodecFactory factory = textCodecMap->get(encoding.name());
    ASSERT(factory.function);
    return factory.function(encoding, factory.additionalData);
}
上面那行红色的代码,encoding.name()的值是"ISO-8859-1",返回的factory却是空的,导致后面调用它的成员函数function时直接Access Violation。

在网上查了一下,发现这个问题早在Qt 4.8.2时就已经存在了,同样的工具链(vs2012 x86),同样的异常代码:
https://bugs.webkit.org/show_bug.cgi?id=90008
好像是HashMap的成员函数get的问题,还没有细查,依照上述链接中的解决方案修改就好了:

将函数:
static void addToTextCodecMap(const char* name, NewTextCodecFunction function, const void* additionalData)
{
    const char* atomicName = textEncodingNameMap->get(name);
    ASSERT(atomicName);
    textCodecMap->add(atomicName, TextCodecFactory(function, additionalData));
}
修改为:
static void addToTextCodecMap(const char* name, NewTextCodecFunction function, const void* additionalData)
{
    // const char* atomicName = textEncodingNameMap->get(name);
    const char* atomicName;
    TextEncodingNameMap::iterator pos;
    for (pos = textEncodingNameMap->begin(); pos != textEncodingNameMap->end(); ++pos) {
        if (strcmp(pos->key, name) == 0) {
            atomicName = pos->value;
            break;
        }
    }
    ASSERT(atomicName);
    textCodecMap->add(atomicName, TextCodecFactory(function, additionalData));
}

将函数:
PassOwnPtr<TextCodec> newTextCodec(const TextEncoding& encoding)
{
    MutexLocker lock(encodingRegistryMutex());
    ASSERT(textCodecMap);
    TextCodecFactory factory = textCodecMap->get(encoding.name());
    ASSERT(factory.function);
    return factory.function(encoding, factory.additionalData);
}
修改为:
PassOwnPtr<TextCodec> newTextCodec(const TextEncoding& encoding)
{
    MutexLocker lock(encodingRegistryMutex());
    ASSERT(textCodecMap);
    // TextCodecFactory factory = textCodecMap->get(encoding.name());
    TextCodecFactory factory;
    TextCodecMap::iterator pos;
    for (pos = textCodecMap->begin(); pos != textCodecMap->end(); ++pos) {
        if (strcmp(pos->key, encoding.name()) == 0) {
            factory = pos->value;
            break;
        }
    }
    ASSERT(factory.function);
    return factory.function(encoding, factory.additionalData);
}

注:Qt5Webkit的KeyValuePair的键/值使用的是key/value,不是原来的first/second。



离线icosagon

只看该作者 2楼 发表于: 2013-01-02
这问题困扰我很久了,难道是vs2012编译器优化的bug?
快速回复
限100 字节
 
上一个 下一个