You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When running the server in gdb, I noticed that when using multiple threads, as soon as they are created they immediately exit, with the exception of the last one created. Here is the output of gdb when running your example hello_world.cpp:
), and noticed that you are handling the creation of multiple threads within libhttpserver. I was under the impression that libmicrohttpd handled the thread pool with the MHD_USE_SELECT_INTERNALLY flag and setting MHD_OPTION_THREAD_POOL_SIZE in the options list (the va_args parameter to MHD_start_daemon).
I have verified that this is not an issue with my setup or libmicrohttpd by running the example in the libmicrohttpd docs with multiple threads, and they do not exit after creation.
I was using libmicrohttpd internal select for long time before changing to the new implementation.
This change (complication) is due to the desire to allow people using the library to implement comet mechanisms and introduce event listener (such as curl to implement proxies) much more easily.
The main mistake here is not the overall implementation but that the "running" flag was set after the threads start and so almost all of them were exiting before the start completion.
This is solved in the last code push. Sorry about this.
I leave this open for a while so that you can notify me, if you want, on other related issues.
Bad News: After this update the server segfaults when a request is received. Below is the output of gdb's backtrace when a request is made to the hello world example:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff3a5a700 (LWP 9272)]
0x0000000000000000 in ?? ()
(gdb) bt
#0 0x0000000000000000 in ?? ()
#1 0x00007ffff7bb9aa7 in httpserver::webserver::finalize_answer(MHD_Connection*, httpserver::details::modded_request*, char const*) () from /usr/lib/libhttpserver.so.0
#2 0x00007ffff7bba893 in httpserver::webserver::bodyless_requests_answer(MHD_Connection*, char const*, char const*, httpserver::details::modded_request*) () from /usr/lib/libhttpserver.so.0
#3 0x00007ffff7bbaef5 in httpserver::webserver::answer_to_connection(void*, MHD_Connection*, char const*, char const*, char const*, char const*, unsigned long*, void**) () from /usr/lib/libhttpserver.so.0
#4 0x00007ffff6dccd69 in ?? () from /usr/lib/libmicrohttpd.so.10
#5 0x00007ffff6dce270 in ?? () from /usr/lib/libmicrohttpd.so.10
#6 0x00007ffff6dd33e9 in MHD_run_from_select () from /usr/lib/libmicrohttpd.so.10
#7 0x00007ffff6dd3691 in ?? () from /usr/lib/libmicrohttpd.so.10
#8 0x00007ffff6dd324b in MHD_run () from /usr/lib/libmicrohttpd.so.10
#9 0x00007ffff7bb3747 in httpserver::webserver::select(void*) () from /usr/lib/libhttpserver.so.0
#10 0x00007ffff63b20a2 in start_thread () from /usr/lib/libpthread.so.0
#11 0x00007ffff70c4d1d in clone () from /usr/lib/libc.so.6
Sounds weird. Since I am currently running the hello_world example without any problem. Do you have any local change (library or example)? Would you be able to compile the library configuring it with the --enable-debug option so that you can have a more detailed stacktrace and sendd me which is the request you execute against the server on the example?
Recompiled with --enable-debug and reinstalled. I installed the library with make install as usual after configuring and building so that doesn't seem to be the issue, and I copied the hello_world example directly from the source tree. This is the backtrace:
#0 0x0000000000000000 in ?? ()
#1 0x00007ffff7b33f3a in httpserver::details::binders::functor_two<MHD_Response**, httpserver::webserver*, void>::operator() (this=0x7fffec009298, p1=0x7ffff51555d8, p2=0x7fffffffe450)
at ../../libhttpserver/src/httpserver/binders.hpp:204
#2 0x00007ffff7b297d8 in httpserver::webserver::finalize_answer (this=0x7fffffffe450, connection=0x7fffec0008c0, mr=0x7fffec008ab0, method=0x7fffec000a80 "GET") at ../../libhttpserver/src/webserver.cpp:1148
#3 0x00007ffff7b2a2d9 in httpserver::webserver::complete_request (this=0x7fffffffe450, connection=0x7fffec0008c0, mr=0x7fffec008ab0, version=0x7fffec000a8b "HTTP/1.1", method=0x7fffec000a80 "GET")
at ../../libhttpserver/src/webserver.cpp:1198
#4 0x00007ffff7b277d2 in httpserver::webserver::bodyless_requests_answer (this=0x7fffffffe450, connection=0x7fffec0008c0, method=0x7fffec000a80 "GET", version=0x7fffec000a8b "HTTP/1.1", mr=0x7fffec008ab0)
at ../../libhttpserver/src/webserver.cpp:889
#5 0x00007ffff7b2a979 in httpserver::webserver::answer_to_connection (cls=0x7fffffffe450, connection=0x7fffec0008c0, url=0x7fffec000a84 "/hello", method=0x7fffec000a80 "GET", version=0x7fffec000a8b "HTTP/1.1",
upload_data=0x0, upload_data_size=0x7ffff5155978, con_cls=0x7fffec000918) at ../../libhttpserver/src/webserver.cpp:1284
#6 0x00007ffff6cc5d69 in ?? () from /usr/lib/libmicrohttpd.so.10
#7 0x00007ffff6cc7270 in ?? () from /usr/lib/libmicrohttpd.so.10
#8 0x00007ffff6ccc3e9 in MHD_run_from_select () from /usr/lib/libmicrohttpd.so.10
#9 0x00007ffff6ccc691 in ?? () from /usr/lib/libmicrohttpd.so.10
#10 0x00007ffff6ccc24b in MHD_run () from /usr/lib/libmicrohttpd.so.10
#11 0x00007ffff7b22719 in httpserver::webserver::select (self=0x6109f0) at ../../libhttpserver/src/webserver.cpp:324
#12 0x00007ffff62ab0a2 in start_thread () from /usr/lib/libpthread.so.0
#13 0x00007ffff6fbdd1d in clone () from /usr/lib/libc.so.6
The request that I made was a GET request to http://localhost:8080/hello.
I'm trying to think of something that could have gone wrong on my end but I can't think of anything :/
The segfault is a result of code changes in the last commit, checking out commit 24ae6ec doesn't segfault, so it appears to be the result of either the addition of the virtual destructor for http_response, or making the destructor of http_resource protected instead of public.
Edit: On further examination, it's the virtual destructor that is causing the segfault.
, it no longer segfaults. The only thing that I can think of is that some of the stuff that is being done in converter with reinterpret_cast is possibly undefined behaviour and my specific compiler is handling it differently then yours :/
Considering the implementation the virtual destructor is much more of a syntactic sugar in this case then else. Anyway this problem underlines that there are some weirdnesses in the implementation that I am not in love with. I will remove the virtual for now and continue to investigate on this since it seems utterly interesting from a language exploration perspective.
Just as a curiosity, can you send me which is the compiler you are using and its version and send to me also the line you use to run the configure?
I have tested it with g++ (GCC) 4.8.2 20140206 (prerelease), as well as clang version 3.4 (tags/RELEASE_34/final). I configured it with ../libhttpserver/configure --prefix=/usr.
It is strongly possible that it is an undefined behaviour.
Honestly I think that the http_response implementation is over-complicated considered its goal. I will probably spend this days in removing all these specific response objects and creating just simple static factory methods inside the http_response object. It sounds like a much more simple and reasonable solution that will make the life easier for the compiler and for a reader/debugger of the code. I am sorry for the fact that this will probably break the backward compatibility.
Activity
etr commentedon May 1, 2014
I was using libmicrohttpd internal select for long time before changing to the new implementation.
This change (complication) is due to the desire to allow people using the library to implement comet mechanisms and introduce event listener (such as curl to implement proxies) much more easily.
The main mistake here is not the overall implementation but that the "running" flag was set after the threads start and so almost all of them were exiting before the start completion.
This is solved in the last code push. Sorry about this.
I leave this open for a while so that you can notify me, if you want, on other related issues.
Thanks!
m-renaud commentedon May 1, 2014
Good News: The threads don't exit right away! :)
Bad News: After this update the server segfaults when a request is received. Below is the output of gdb's backtrace when a request is made to the hello world example:
etr commentedon May 2, 2014
Sounds weird. Since I am currently running the hello_world example without any problem. Do you have any local change (library or example)? Would you be able to compile the library configuring it with the --enable-debug option so that you can have a more detailed stacktrace and sendd me which is the request you execute against the server on the example?
Thanks
m-renaud commentedon May 2, 2014
Recompiled with --enable-debug and reinstalled. I installed the library with
make installas usual after configuring and building so that doesn't seem to be the issue, and I copied the hello_world example directly from the source tree. This is the backtrace:The request that I made was a GET request to
http://localhost:8080/hello.I'm trying to think of something that could have gone wrong on my end but I can't think of anything :/
m-renaud commentedon May 2, 2014
The segfault is a result of code changes in the last commit, checking out commit 24ae6ec doesn't segfault, so it appears to be the result of either the addition of the virtual destructor for http_response, or making the destructor of http_resource protected instead of public.
Edit: On further examination, it's the virtual destructor that is causing the segfault.
etr commentedon May 2, 2014
Cool, Do you have details about the virtual destructor causing this? It could help in fixing it since I am not being able to manifest the problem :(
m-renaud commentedon May 2, 2014
I have tracked it down to the call
_binder.get_mem_ptr()herelibhttpserver/src/httpserver/binders.hpp
Line 204 in 3696904
->*.The bizarre thing is, if I remove the
virtualfrom the http_response destructor atlibhttpserver/src/httpserver/http_response.hpp
Line 212 in 5e7eb07
converterwith reinterpret_cast is possibly undefined behaviour and my specific compiler is handling it differently then yours :/etr commentedon May 2, 2014
Considering the implementation the virtual destructor is much more of a syntactic sugar in this case then else. Anyway this problem underlines that there are some weirdnesses in the implementation that I am not in love with. I will remove the virtual for now and continue to investigate on this since it seems utterly interesting from a language exploration perspective.
Just as a curiosity, can you send me which is the compiler you are using and its version and send to me also the line you use to run the configure?
Thanks!
m-renaud commentedon May 2, 2014
I have tested it with
g++ (GCC) 4.8.2 20140206 (prerelease), as well asclang version 3.4 (tags/RELEASE_34/final). I configured it with../libhttpserver/configure --prefix=/usr.heinermann commentedon May 2, 2014
I'm working with the same codebase as @mrenaud92 and I don't get the segfault.
I've tried the following:
g++ (Ubuntu 4.9-20140406-1ubuntu1) 4.9.0 20140405 (experimental) [trunk revision 209157]Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4)I was unable to reproduce the error.
There may be some kind of undefined behaviour involved which affects certain builds or systems. Either way we have no idea what is causing the issue.
@mrenaud92 mentioned that it might be related to
reinterpret_casts.etr commentedon May 2, 2014
It is strongly possible that it is an undefined behaviour.
Honestly I think that the http_response implementation is over-complicated considered its goal. I will probably spend this days in removing all these specific response objects and creating just simple static factory methods inside the http_response object. It sounds like a much more simple and reasonable solution that will make the life easier for the compiler and for a reader/debugger of the code. I am sorry for the fact that this will probably break the backward compatibility.
m-renaud commentedon May 3, 2014
Broken backwards compatibility isn't a big issue, it shouldn't take much time to change it over to the new API once it's finished.
etr commentedon May 11, 2014
pushed out the new interface based on builder object.
The http_response class is now non-modifiable by public code.
I close this issue. Feel free to open an issue if you see any other problem.
Thanks!
TASK-051 Tier 3: address 2nd-pass review findings (fix/task-051-2nd-r…