New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault when using a long URL path #861

Closed
skirino opened this Issue Oct 12, 2014 · 1 comment

Comments

Projects
None yet
2 participants
@skirino

skirino commented Oct 12, 2014

With a long static URL path, something wrong happens in the routing layer and the first request results in a crash (SIGSEGV).
A minimal program with VibeDefaultMain that reproduces the problem is as follows:

import vibe.d;

void handler(HTTPServerRequest req, HTTPServerResponse res) {
  res.redirect("http://www.example.com");
}

shared static this() {
  auto router = new URLRouter;
  router.get("/abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG", &handler);
  //router.rebuild();
  auto settings = new HTTPServerSettings;
  settings.port = 8080;
  listenHTTP(settings, router);
}

My setup:

  • dmd: v2.065.0
  • vibe.d: 0.7.20 and 0.7.21-rc.1
    • Not reproducible with 0.7.19
  • OS: Linux 3.16.2-1-MANJARO
    • Not reproducible on OSX (still 10.8 ...) with the same dmd and vibe.d versions

A few things that might be helpful:

  • Threshold length of the URL path:
    • The URL in the example above is the threshold in my environment: abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG (43 characters long).
    • Static URL paths with lengths >= 43 suffers from the issue.
    • If all lengths of paths registered to the router are < 43, then the issue don't happen.
  • Workaround I found:
    • By explicitly calling router.rebuild() after router.get() the issue can be avoided.
  • Using vibe.d 0.7.20, I got the following stack trace by $ curl localhost:8080/.
Program received signal SIGSEGV, Segmentation fault.
0x000000000055b175 in _d_arraysetlengthiT ()
(gdb) bt
#0  0x000000000055b175 in _d_arraysetlengthiT ()
#1  0x0000000000458e5c in _D4vibe4http6router39__T9MatchTreeTS4vibe4http6router5RouteZ9MatchTree12rebuildGraphMFZv7processMFmZk (
    this=0x7ffff7fe6268, n=46) at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/router.d:592
#2  0x00000000004591c0 in _D4vibe4http6router39__T9MatchTreeTS4vibe4http6router5RouteZ9MatchTree12rebuildGraphMFZv7processMFmZk (
    this=0x7ffff7fe6268, n=45) at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/router.d:604

... (recursive calls to _D4vibe4http6router39__T9MatchTreeTS4vibe4http6router5RouteZ9MatchTree12rebuildGraphMFZv7processMFmZk) ...

#46 0x00000000004591c0 in _D4vibe4http6router39__T9MatchTreeTS4vibe4http6router5RouteZ9MatchTree12rebuildGraphMFZv7processMFmZk (
    this=0x7ffff7fe6268, n=1) at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/router.d:604
#47 0x0000000000458d3a in _D4vibe4http6router39__T9MatchTreeTS4vibe4http6router5RouteZ9MatchTree12rebuildGraphMFZv (this=0x7ffff7ed0810)
    at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/router.d:611
#48 0x0000000000457f8d in _D4vibe4http6router39__T9MatchTreeTS4vibe4http6router5RouteZ9MatchTree5matchMFAyaMDFmMAAyaZvZv (
    this=0x7ffff7ed0810, del=..., text=...) at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/router.d:456
#49 0x0000000000457871 in vibe.http.router.URLRouter.handleRequest(vibe.http.server.HTTPServerRequest, vibe.http.server.HTTPServerResponse) (
    this=0x7ffff7ed0800, res=0x90fb80, req=0x7ffff7e9a020) at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/router.d:155
#50 0x00000000004db768 in vibe.http.server.handleRequest(vibe.core.stream.Stream, vibe.core.net.TCPConnection, vibe.http.server.HTTPServerListener, ref vibe.http.server.HTTPServerSettings, ref bool) (keep_alive=0x7ffff7fe6cf0, settings=0x7ffff7fe6ce8, listen_info=..., 
    tcp_connection=0x90f628, http_stream=0x90f628) at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/server.d:1412
#51 0x00000000004da033 in vibe.http.server.handleHTTPConnection(vibe.core.net.TCPConnection, vibe.http.server.HTTPServerListener) (
    listen_info=..., connection=0x90f628) at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/server.d:1201
#52 0x00000000004d9d20 in vibe.http.server.listenHTTPPlain(vibe.http.server.HTTPServerSettings).doListen(vibe.http.server.HTTPServerSettings, vibe.http.server.HTTPServerListener, immutable(char)[]).__lambda4(vibe.core.net.TCPConnection) (this=0x7ffff7ec9380, conn=0x90f628)
    at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/http/server.d:121
#53 0x000000000043a180 in vibe.core.drivers.libevent2_tcp.onConnect(int, short, void*).ClientTask.execute() (this=0x90da60)
    at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/core/drivers/libevent2_tcp.d:509
#54 0x0000000000426fbb in _D4vibe4core4core12__T7runTaskZ7runTaskFDFZvZS4vibe4core4task4Task12callDelegateFC4vibe4core4core8CoreTaskZv (
    fiber=0x7ffff7ecb200) at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/core/core.d:196
#55 0x0000000000423462 in vibe.core.core.CoreTask.run() (this=0x7ffff7ecb200)
    at ../../../../.dub/packages/vibe-d-0.7.20/source/vibe/core/core.d:879
#56 0x0000000000590912 in core.thread.Fiber.run() ()
#57 0x000000000059081d in fiber_entryPoint ()
#58 0x0000000000000000 in ?? ()

Any ideas?

@s-ludwig s-ludwig added this to the 0.7.21 milestone Oct 13, 2014

@s-ludwig

This comment has been minimized.

Show comment
Hide comment
@s-ludwig

s-ludwig Oct 13, 2014

Member

Seems like this is simply a stack overflow in a recursive algorithm due to the very conservative choice of the stack size for tasks (64K). As a workaround, you can call setTaskStackSize(1024*1024); or similar at initialization time.

I'll probably just increase the default to something like 512K on 32-bit systems and 16M on 64-bit systems.

Member

s-ludwig commented Oct 13, 2014

Seems like this is simply a stack overflow in a recursive algorithm due to the very conservative choice of the stack size for tasks (64K). As a workaround, you can call setTaskStackSize(1024*1024); or similar at initialization time.

I'll probably just increase the default to something like 512K on 32-bit systems and 16M on 64-bit systems.

@s-ludwig s-ludwig closed this in 9020e9f Oct 13, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment