[Libwebsockets] wide strings and _lws_log

Andy Green andy at warmcat.com
Tue May 15 01:33:26 CEST 2018



On 05/15/2018 07:21 AM, Alexander Bruines wrote:
> Hello Andy,
> 
> Congratulations on the 3.0 release of libwebsockets!
> 
> I may have discovered a minor issue with _lws_log() when using C++. It produces errors when printing a std::wstring.

... okay... personally I only use utf-8.

> Please consider the following code snippet and the output that valgrind produces:
> 
> #include <iostream>
> #include <cwchar>
> #include <string>
> #include "libwebsockets.h"
> 
> void wide_log_emit_func(int level, const char* str) {
>    fwprintf(stderr, L"%s", str);
> }
> 
> int main(int argc, char** argv) {
>    using namespace std;
> 
>    fwprintf(stderr, L"Assigning a wide orientation to stderr.\n");
> 
>    wstring error = L"Horrible valgrind errors when printed with _lws_log!";
>    const wchar_t* okay = L"This is okay.";
> 
>    // Does not matter for the valgrind errors.
>    // Not doing this just results in _lws_log not print anything
>    // due to the wide orientation of stderr.

"wide orientation of stderr"... what does that mean?

If I am sitting here with LANG=en_US.UTF-8, whatever that means applies?

>    lws_set_log_level(LLL_ERR, wide_log_emit_func);
> 
>    // This works fine.
>    fwprintf(stderr, L"fwprintf: %ls\n", error.c_str());
> 
>    // This also works without valgrind errors, but does not output anything
>    // due to the wide orientation of stderr.
>    fprintf(stderr, "fprintf: %ls\n", error.c_str());
> 
>    // This also works.
>    _lws_log(LLL_ERR, "_lws_log: %ls\n", okay);
> 
>    // Valgrind: Conditional jump or move depends on uninitialised value(s)
>    _lws_log(LLL_ERR, "_lws_log: %ls\n", error.c_str());
> 
>    return 0;
> }
> 
> Valgrind output:
> 
> ==2276== Memcheck, a memory error detector
> ==2276== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
> ==2276== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
> ==2276== Command: src/test/vgtest
> ==2276==
> Assigning a wide orientation to stderr.
> fwprintf: Horrible valgrind errors when printed with _lws_log!
> _lws_log: This is okay.
> ==2276== Conditional jump or move depends on uninitialised value(s)
> ==2276==    at 0x65E3EB7: __wcsnlen_avx2 (strlen-avx2.S:275)
> ==2276==    by 0x652B811: wcsrtombs (wcsrtombs.c:104)
> ==2276==    by 0x64D8B16: vfprintf (vfprintf.c:1643)
> ==2276==    by 0x658E8C8: __vsnprintf_chk (vsnprintf_chk.c:63)
> ==2276==    by 0x10DCCD: vsnprintf (stdio2.h:77)

Yeah we just call vnsprintf with the va_list.  We don't know or care if 
they are normal char *s or ints or wide or whatever.

He seems to overrun the set part of the wide string doing a "wide 
strlen" from inside vnsprintf... I don't see how lws causes that.

What is your libc?

> ==2276==    by 0x10DCCD: _lws_logv.part.7 (libwebsockets.c:1977)
> ==2276==    by 0x10EC2B: _lws_logv (libwebsockets.c:1974)
> ==2276==    by 0x10EC2B: _lws_log (libwebsockets.c:1993)
> ==2276==    by 0x10DA2F: main (vgtest.cpp:34)
> ==2276==
> ==2276== Conditional jump or move depends on uninitialised value(s)
> ==2276==    at 0x64AEF78: internal_ascii_loop (loop.c:298)
> ==2276==    by 0x64AEF78: __gconv_transform_internal_ascii (skeleton.c:609)
> ==2276==    by 0x652B844: wcsrtombs (wcsrtombs.c:110)
> ==2276==    by 0x64D8B16: vfprintf (vfprintf.c:1643)
> ==2276==    by 0x658E8C8: __vsnprintf_chk (vsnprintf_chk.c:63)
> ==2276==    by 0x10DCCD: vsnprintf (stdio2.h:77)
> ==2276==    by 0x10DCCD: _lws_logv.part.7 (libwebsockets.c:1977)
> ==2276==    by 0x10EC2B: _lws_logv (libwebsockets.c:1974)
> ==2276==    by 0x10EC2B: _lws_log (libwebsockets.c:1993)
> ==2276==    by 0x10DA2F: main (vgtest.cpp:34)
> ==2276==
> ==2276== Conditional jump or move depends on uninitialised value(s)
> ==2276==    at 0x64AEF81: internal_ascii_loop (loop.c:303)
> ==2276==    by 0x64AEF81: __gconv_transform_internal_ascii (skeleton.c:609)
> ==2276==    by 0x652B844: wcsrtombs (wcsrtombs.c:110)
> ==2276==    by 0x64D8B16: vfprintf (vfprintf.c:1643)
> ==2276==    by 0x658E8C8: __vsnprintf_chk (vsnprintf_chk.c:63)
> ==2276==    by 0x10DCCD: vsnprintf (stdio2.h:77)
> ==2276==    by 0x10DCCD: _lws_logv.part.7 (libwebsockets.c:1977)
> ==2276==    by 0x10EC2B: _lws_logv (libwebsockets.c:1974)
> ==2276==    by 0x10EC2B: _lws_log (libwebsockets.c:1993)
> ==2276==    by 0x10DA2F: main (vgtest.cpp:34)
> ==2276==
> ==2276== Conditional jump or move depends on uninitialised value(s)
> ==2276==    at 0x64AEFBC: internal_ascii_loop (loop.c:298)
> ==2276==    by 0x64AEFBC: __gconv_transform_internal_ascii (skeleton.c:609)
> ==2276==    by 0x652B844: wcsrtombs (wcsrtombs.c:110)
> ==2276==    by 0x64D8B16: vfprintf (vfprintf.c:1643)
> ==2276==    by 0x658E8C8: __vsnprintf_chk (vsnprintf_chk.c:63)
> ==2276==    by 0x10DCCD: vsnprintf (stdio2.h:77)
> ==2276==    by 0x10DCCD: _lws_logv.part.7 (libwebsockets.c:1977)
> ==2276==    by 0x10EC2B: _lws_logv (libwebsockets.c:1974)
> ==2276==    by 0x10EC2B: _lws_log (libwebsockets.c:1993)
> ==2276==    by 0x10DA2F: main (vgtest.cpp:34)
> ==2276==
> _lws_log: Horrible valgrind errors when printed with _lws_log!
> ==2276==
> ==2276== HEAP SUMMARY:
> ==2276==     in use at exit: 5,120 bytes in 2 blocks
> ==2276==   total heap usage: 4 allocs, 2 frees, 78,036 bytes allocated
> ==2276==
> ==2276== LEAK SUMMARY:
> ==2276==    definitely lost: 0 bytes in 0 blocks
> ==2276==    indirectly lost: 0 bytes in 0 blocks
> ==2276==      possibly lost: 0 bytes in 0 blocks
> ==2276==    still reachable: 5,120 bytes in 2 blocks
> ==2276==         suppressed: 0 bytes in 0 blocks
> ==2276== Rerun with --leak-check=full to see details of leaked memory
> ==2276==
> ==2276== For counts of detected and suppressed errors, rerun with: -v
> ==2276== Use --track-origins=yes to see where uninitialised values come from
> ==2276== ERROR SUMMARY: 108 errors from 4 contexts (suppressed: 0 from 0)
> 
> My current workaround is to not use _lws_log for my own code (but that was very convenient when using it with LLL_USER).

If you use vnsprintf() to prepare your logs for printing, there is no 
problem?

-Andy

> Kind regards,
> 
> Alexander
> 
> _______________________________________________
> Libwebsockets mailing list
> Libwebsockets at ml.libwebsockets.org
> https://libwebsockets.org/mailman/listinfo/libwebsockets
> 



More information about the Libwebsockets mailing list