vswprintf崩溃

时间:2008-10-17 21:11:22

标签: c++ symbian posix

使用10月2日发布的Symbian S60第5版SDK,我正在编译/运行(在sim上)以下代码片段:

void test(wchar_t *dest, int size, const wchar_t *fmt, ...) {
    va_list vl;
    va_start(vl, fmt);
    vswprintf(dest, size, fmt, vl);
    va_end(vl);
}

...

wchar_t str[1024];

// this crashes (2nd string 123 characters (+ \0) equals 248 bytes)
test(str, 1024, L"msg: %S", L"this is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a tes");

// this works (2nd string 122 characters (+ \0) equals 246 bytes)
test(str, 1024, L"msg: %S", L"this is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a test messagethis is a te");

对于我来说没有任何明显的理由(即使在阅读vswprintf手册页一百次之后),我可以弄清楚为什么这个代码在vswprintf调用长字符串时崩溃了我:-(完全相同代码在Linux机器上工作正常。有足够的内存分配给str,另外vswprintf正在检查缓冲区溢出。不幸的是...... S60调试器没有破坏这个崩溃,所以我没有细节: - (

有人有什么想法吗?

假设Symbian的vswprintf例程存在错误,那么使用符合POSIX标准的代码可能会有什么替换功能? (这应该是一个跨平台的库)

感谢。

6 个答案:

答案 0 :(得分:1)

对我来说,这似乎是一个步入vswprintf()电话的工作。即使您只能进行汇编级调试,也应该清楚通过监视str[]内存中的内容来进行更多或更少的操作。

答案 1 :(得分:1)

我碰巧在vswprintf的实现中找到了一个内部缓冲区,硬编码为128字节。这很可能会导致长字符串崩溃。

答案 2 :(得分:0)

将%S更改为%s - 将大写更改为小写。

在基于MS的printfs中,%S表示unicode字符,因此这就是123字符串失败的原因,它预计每个字符有2个字节。 (注意%S不是标准的一部分,因此这里的Symbian可能不同)

实际上,我认为这仍然适用于Symbian

答案 3 :(得分:0)

您可以尝试将%S格式说明符更改为%ls。正如我之前的评论中所提到的,它们应该是等价的,但实现中可能存在错误。请注意,vswprintf函数是在C99标准中定义的,因为还没有任何完全符合C99的编译器(我相信),vswprintf的任何给定实现很可能不完全符合规范,或者它包含错误(前者比后者更可能)。

答案 4 :(得分:0)

你可以尝试不调用test()并使用swprintf - 如果bug与VARARGS处理有关吗?

答案 5 :(得分:0)

我现在通过使用Symbian函数来“解决”这个问题:

void test(wchar_t *dest, int size, const wchar_t *fmt, ...) {
    VA_LIST args;
    VA_START(args, fmt);

    TPtrC16 fmtPtr((const TUint16*)fmt, wcslen(fmt) + 1);  
    TPtr16  targetPtr((TUint16*)dest, size);

    targetPtr.FormatList(fmtPtr, args);
    targetPtr.ZeroTerminate();

    VA_END(args);
}

(在这种情况下,你实际上必须use %s