[Libwebsockets] wide strings and _lws_log

Alexander Bruines alexander.bruines at gmail.com
Tue May 15 01:21:13 CEST 2018


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.

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.
  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)
==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).

Kind regards,

Alexander



More information about the Libwebsockets mailing list