<div dir="ltr"><div dir="ltr">Thanks Silas for your explanation.<div>I was aware about this warning (I'm compiling with -Wall flag) but I was not thinking it may have a so big impact and be the cause of this issue. Nevertheless, because I'm not able to follow carefully the compiler implementations (I'm working in a far way area), I know now that fixing warnings is a pre-requisite before anything - We learning's new things everyday... </div><div><br></div><div>Thanks again / Best Regards </div><div><br></div><div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Nov 19, 2019 at 7:43 PM Silas Parker <<a href="mailto:skyhisi%2Blibwebsockets@gmail.com">skyhisi+libwebsockets@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Hi Gilles,<br>
<br>
The missing statement has triggered "undefined behaviour", this means<br>
the compiler may generate no code, "bad" code, or anything else it<br>
likes.<br>
<br>
In the C++ specification section 6.6.3 "The return statement" it says:<br>
"Flowing off the end of a function is equivalent to a return with no<br>
value; this results in undefined behavior in a value-returning<br>
function."<br>
<br>
If you've declared that a function returns a value, but then don't<br>
return one, what should the compiler generate? The function that<br>
called it needs a value, so what should it use?<br>
<br>
Even with optimisation disabled (-O0) the compiler generates different<br>
code depending on if the return statement is present. Without the<br>
return, it generates the "ret", but it doesn't set the EAX register<br>
(the register used for return values), so the return value from the<br>
function would be whatever junk had been previously left in EAX by<br>
other code. When in -O2, it just omits the "ret" completely as<br>
mentioned previously.<br>
<br>
The behaviour with the LLVM compiler is similar to GCC, the MSVC<br>
compiler refuses to generate code. Have a play around in Compiler<br>
Explorer which I linked to before, it's very interesting to see what<br>
C/C++ code turns into at the assembly level.<br>
<br>
Thanks,<br>
Silas<br>
<br>
On Tue, 19 Nov 2019 at 13:57, Andy Green <<a href="mailto:andy@warmcat.com" target="_blank">andy@warmcat.com</a>> wrote:<br>
><br>
><br>
><br>
> On November 19, 2019 1:42:44 PM GMT, Gilles Printemps <<a href="mailto:gprintemps@gmail.com" target="_blank">gprintemps@gmail.com</a>> wrote:<br>
> >Hi Silas,<br>
> >You're right - Fixing this warning resolved the issue with the -02 flag<br>
> >Is it possible for you to provide details and to explain why the<br>
> >missing<br>
> >statement (return 0) is producing this behaviour (lws callback called<br>
> >many<br>
> >times after the destroy with bad parameters) ?<br>
> ><br>
> >>>> Reason [65535] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[(nil)]<br>
> >Reason [65535] not handled<br>
> >>>> Reason [0] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >>>> Reason [1706065] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >Reason [1706065] not handled<br>
> >>>> Reason [0] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >>>> Reason [1706065] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >Reason [1706065] not handled<br>
> >>>> Reason [0] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >>>> Reason [1706065] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >Reason [1706065] not handled<br>
> >>>> Reason [0] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >>>> Reason [1706065] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >Reason [1706065] not handled<br>
> >>>> Reason [0] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >>>> Reason [1706065] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >Reason [1706065] not handled<br>
> >>>> Reason [0] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> >>>> Reason [1706065] wsi [(nil)] session [0xa1f4f25cc05cbb00] data<br>
> >[0xffff8a0388c0]<br>
> ><br>
> ><br>
> >I tried with a lot compiler and confirm it is working without the<br>
> >return<br>
> >statement<br>
><br>
> It's great Silas figured it out.<br>
><br>
> It's blowing a warning telling you to return something IIUI... if it empirically "worked" it's just by accident of what was on the stack or in a register by chance.  The big lesson to be had here to save yourself next time is not exact details of how that trashed parameters to subsequent calls, but "build your stuff with -Werror (like lws does) and understand what was behind every warning".<br>
><br>
> -Andy<br>
><br>
> >Using built-in specs.<br>
> >COLLECT_GCC=g++<br>
> >COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper<br>
> >Target: x86_64-linux-gnu<br>
> >Configured with: ../src/configure -v --with-pkgversion='Ubuntu<br>
> >5.4.0-6ubuntu1~16.04.12'<br>
> >--with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs<br>
> >--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++<br>
> >--prefix=/usr<br>
> >--program-suffix=-5 --enable-shared --enable-linker-build-id<br>
> >--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix<br>
> >--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu<br>
> >--enable-libstdcxx-debug --enable-libstdcxx-time=yes<br>
> >--with-default-libstdcxx-abi=new --enable-gnu-unique-object<br>
> >--disable-vtable-verify --enable-libmpx --enable-plugin<br>
> >--with-system-zlib<br>
> >--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo<br>
> >--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre<br>
> >--enable-java-home<br>
> >--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64<br>
> >--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64<br>
> >--with-arch-directory=amd64<br>
> >--with-ecj-jar=/usr/share/java/eclipse-ecj.jar<br>
> >--enable-objc-gc --enable-multiarch --disable-werror<br>
> >--with-arch-32=i686<br>
> >--with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib<br>
> >--with-tune=generic --enable-checking=release --build=x86_64-linux-gnu<br>
> >--host=x86_64-linux-gnu --target=x86_64-linux-gnu<br>
> >Thread model: posix<br>
> >gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)<br>
> ><br>
> ><br>
> >Thanks for your help but now, as mentioned, I would like to<br>
> >understand...<br>
> ><br>
> >On Tue, Nov 19, 2019 at 2:11 PM Silas Parker <<br>
> ><a href="mailto:skyhisi%2Blibwebsockets@gmail.com" target="_blank">skyhisi+libwebsockets@gmail.com</a>> wrote:<br>
> ><br>
> >> If you compile your code with warnings on, you should see the<br>
> >following:<br>
> >> Main.cpp: In function ‘void* waitingLoop(void*)’:<br>
> >> Main.cpp:11:1: warning: no return statement in function returning<br>
> >> non-void [-Wreturn-type]<br>
> >>    11 | }<br>
> >>       | ^<br>
> >><br>
> >> If you add a "return 0;" to your thread function, then it'll work.<br>
> >> It's nothing to do with libwebsockets.<br>
> >><br>
> >> If you use Compiler Explorer, you can see that modern versions of GCC<br>
> >> won't generate the ret instruction if you forget to put the return<br>
> >> statement in your code when optimisations are enabled.<br>
> >> <a href="https://gcc.godbolt.org/z/sk8B-U" rel="noreferrer" target="_blank">https://gcc.godbolt.org/z/sk8B-U</a><br>
> >><br>
> >> Thanks,<br>
> >> Silas<br>
> >><br>
> >> On Tue, 19 Nov 2019 at 12:43, Gilles Printemps <<a href="mailto:gprintemps@gmail.com" target="_blank">gprintemps@gmail.com</a>><br>
> >> wrote:<br>
> >> ><br>
> >> > Hi Andy,<br>
> >> > The provided program is even smaller than the supplied minimal<br>
> >examples.<br>
> >> >   It is doing nothing except creating a context and destroying it<br>
> >within<br>
> >> a Thread<br>
> >> > However, it has something this is not tested in lws samples: It is<br>
> >> enclosed into c++ class<br>
> >> > If there is something similar in lws, can you give me a link and I<br>
> >will<br>
> >> check/test it...<br>
> >> ><br>
> >> > On Tue, Nov 19, 2019 at 1:35 PM Andy Green <<a href="mailto:andy@warmcat.com" target="_blank">andy@warmcat.com</a>><br>
> >wrote:<br>
> >> >><br>
> >> >><br>
> >> >><br>
> >> >> On 11/19/19 12:27 PM, Gilles Printemps wrote:<br>
> >> >> > Hi Andy,<br>
> >> >> > I tried to reduce to the minimum the program to highlight the<br>
> >issue.<br>
> >> >><br>
> >> >> That's not really what I meant... I mean if you build the supplied<br>
> >> >> minimal examples, without any of your code, do they also behave<br>
> >like<br>
> >> >> this?  You're basically saying it blows up while destroying the<br>
> >context,<br>
> >> >> but that does not happen here with the provided examples.<br>
> >> >><br>
> >> >> If it happens just with lws code, it sounds like something I will<br>
> >have<br>
> >> >> to study.  But if it only happens with your code, it sounds like<br>
> >> >> something you need to study.  Valgrind is very useful.<br>
> >> >><br>
> >> >> -Andy<br>
> >> >><br>
> >> >> > You can find in attachment the 3 files<br>
> >> >> > Regarding the compilation, flags are the following:<br>
> >> >> >    CPPFLAGS (Debug): -DDEBUG -g -O0 -fsanitize=address<br>
> >> >> > -fno-omit-frame-pointer<br>
> >> >> >    CPPFLAGS (Release): -g -Wall -O2 -Wstrict-aliasing<br>
> >> >> >    LDFLAGS (Debug): -fsanitize=address<br>
> >> >> >    LDFLAGS (Release):<br>
> >> >> ><br>
> >> >> > FYI, I currently compiling with g++ on Raspberry Pi 4 model B<br>
> >based on<br>
> >> >> > Ubuntu<br>
> >> >> > Using built-in specs.<br>
> >> >> > COLLECT_GCC=g++<br>
> >> >> > COLLECT_LTO_WRAPPER=/usr/lib/gcc/aarch64-linux-gnu/9/lto-wrapper<br>
> >> >> > Target: aarch64-linux-gnu<br>
> >> >> > Configured with: ../src/configure -v --with-pkgversion='Ubuntu<br>
> >> >> > 9.2.1-9ubuntu2'<br>
> >--with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs<br>
> >> >> > --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,gm2<br>
> >> --prefix=/usr<br>
> >> >> > --with-gcc-major-version-only --program-suffix=-9<br>
> >> >> > --program-prefix=aarch64-linux-gnu- --enable-shared<br>
> >> >> > --enable-linker-build-id --libexecdir=/usr/lib<br>
> >> >> > --without-included-gettext --enable-threads=posix<br>
> >--libdir=/usr/lib<br>
> >> >> > --enable-nls --enable-bootstrap --enable-clocale=gnu<br>
> >> >> > --enable-libstdcxx-debug --enable-libstdcxx-time=yes<br>
> >> >> > --with-default-libstdcxx-abi=new --enable-gnu-unique-object<br>
> >> >> > --disable-libquadmath --disable-libquadmath-support<br>
> >--enable-plugin<br>
> >> >> > --enable-default-pie --with-system-zlib<br>
> >--with-target-system-zlib=auto<br>
> >> >> > --enable-multiarch --enable-fix-cortex-a53-843419<br>
> >--disable-werror<br>
> >> >> > --enable-checking=release --build=aarch64-linux-gnu<br>
> >> >> > --host=aarch64-linux-gnu --target=aarch64-linux-gnu<br>
> >> >> > Thread model: posix<br>
> >> >> > gcc version 9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2)<br>
> >> >> ><br>
> >> >> > Hope it will be useful to find the issue<br>
> >> >> ><br>
> >> >> > On Tue, Nov 19, 2019 at 11:44 AM Andy Green <<a href="mailto:andy@warmcat.com" target="_blank">andy@warmcat.com</a><br>
> >> >> > <mailto:<a href="mailto:andy@warmcat.com" target="_blank">andy@warmcat.com</a>>> wrote:<br>
> >> >> ><br>
> >> >> ><br>
> >> >> ><br>
> >> >> >     On 11/19/19 10:30 AM, Gilles Printemps wrote:<br>
> >> >> >      > Hi,<br>
> >> >> >      > I would like to understand which events should be<br>
> >received by<br>
> >> the<br>
> >> >> >      > callback when "lws_context_destroy" function is called.<br>
> >> >> >      ><br>
> >> >> >      > Currently, in debug mode, I have the following trace:<br>
> >> >> >      ><br>
> >> >> >      >     [2019/11/19 10:01:57:4407] I: lws_context_destroy:<br>
> >ctx<br>
> >> >> >     0xffff99a03280<br>
> >> >> >      >     [2019/11/19 10:01:57:4408] I: lws_destroy_event_pipe<br>
> >> >> >      >     [2019/11/19 10:01:57:4409] I: __lws_close_free_wsi:<br>
> >> >> >     0xffff98203500:<br>
> >> >> >      >     caller: ctx destroy<br>
> >> >> >      >      >>> Reason [30] wsi [0xffff98203500] session [(nil)]<br>
> >data<br>
> >> >> >     [(nil)]<br>
> >> >> >      >      >>> Protocol [0xffff9a202820]<br>
> >> >> >      >     [2019/11/19 10:01:57:4411] I: lws_vhost_unbind_wsi:<br>
> >vh<br>
> >> default:<br>
> >> >> >      >     count_bound_wsi 0<br>
> >> >> >      >     [2019/11/19 10:01:57:4412] I: lws_vhost_destroy1<br>
> >> >> >      >     [2019/11/19 10:01:57:4413] I: lws_context_destroy2:<br>
> >ctx<br>
> >> >> >     0xffff99a03280<br>
> >> >> >      >      >>> Reason [28] wsi [0xffffe73b2750] session [(nil)]<br>
> >data<br>
> >> >> >     [(nil)]<br>
> >> >> >      >      >>> Protocol [0xffff9a202820]<br>
> >> >> >      >     [2019/11/19 10:01:57:4414] I: __lws_vhost_destroy2:<br>
> >> >> >     0xffff98203880<br>
> >> >> >      >     [2019/11/19 10:01:57:4415] I:   __lws_vhost_destroy2:<br>
> >> Freeing<br>
> >> >> >     vhost<br>
> >> >> >      >     0xffff98203880<br>
> >> >> >      >     [2019/11/19 10:01:57:4416] I: lws_context_destroy3:<br>
> >ctx<br>
> >> >> >      >     0xffff99a03280 freed<br>
> >> >> >      >     WebSocket Server stopped<br>
> >> >> >      ><br>
> >> >> >      ><br>
> >> >> >      > But in release mode (with -O2 optimisation), I have<br>
> >something<br>
> >> >> >     different<br>
> >> >> >      > and strange:<br>
> >> >> >      ><br>
> >> >> >      >      >>> Reason [1] wsi [0xaaaaedae9eb0] session [(nil)]<br>
> >data<br>
> >> [(nil)]<br>
> >> >> >      >      >>> Protocol [(nil)]<br>
> >> >> >      >      >>> Reason [-8707407386353682176] wsi [(nil)]<br>
> >session<br>
> >> >> >      >     [0xffffa4b03928] data [0xffffa431c8c0]<br>
> >> >> >      >     Segmentation fault (core dumped)<br>
> >> >> ><br>
> >> >> >     Well, wsi shouldn't be NULL.  For the cases where the event<br>
> >is not<br>
> >> >> >     actually related to a wsi, like a systemwide or vhost<br>
> >related<br>
> >> event,<br>
> >> >> >     lws<br>
> >> >> >     keeps a fake wsi in the per-thread struct in the context so<br>
> >it<br>
> >> can set<br>
> >> >> >     the content, vhost and maybe the protocol in there and pass<br>
> >that<br>
> >> as the<br>
> >> >> >     wsi for the callback.<br>
> >> >> ><br>
> >> >> >      > It is ending by a segmentation fault because I'm trying<br>
> >to<br>
> >> >> >     retrieve the<br>
> >> >> >      > protocol with a wsi which is equal to NULL a the entrance<br>
> >of<br>
> >> the<br>
> >> >> >     callback.<br>
> >> >> >      ><br>
> >> >> >      >     int WebSocketServer::callback(struct lws *wsi,enum<br>
> >> >> >      >     lws_callback_reasons reason,void *session,void<br>
> >*data,size_t<br>
> >> >> >     len) {<br>
> >> >> >      >        const struct lws_protocols *protocol=NULL;<br>
> >> >> >      >        Tools::debug(">>> Reason [%ld] wsi [%p] session<br>
> >[%p]<br>
> >> data<br>
> >> >> >      >     [%p]\n",reason,wsi,session,data);<br>
> >> >> >      >        Tools::debug(">>> Protocol<br>
> >> [%p]\n",lws_get_protocol(wsi));<br>
> >> >> >      ><br>
> >> >> >      >   Seem also the reason is wrong!!!<br>
> >> >> >      ><br>
> >> >> >      > Where did the strange behavior can come from?<br>
> >> >> ><br>
> >> >> >     Dunno.  Does it exist on the lws minimal examples?<br>
> >> >> ><br>
> >> >> >     What I'd do is run it under valgrind, not so much for the<br>
> >leak<br>
> >> >> >     detection<br>
> >> >> >     but it also allows it to spew backtraces as soon as<br>
> >something<br>
> >> goes off<br>
> >> >> >     the rails.<br>
> >> >> ><br>
> >> >> >     -Andy<br>
> >> >> ><br>
> >> ><br>
> >> > _______________________________________________<br>
> >> > Libwebsockets mailing list<br>
> >> > <a href="mailto:Libwebsockets@ml.libwebsockets.org" target="_blank">Libwebsockets@ml.libwebsockets.org</a><br>
> >> > <a href="https://libwebsockets.org/mailman/listinfo/libwebsockets" rel="noreferrer" target="_blank">https://libwebsockets.org/mailman/listinfo/libwebsockets</a><br>
> >><br>
</blockquote></div>