Skip to content
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

SIGSEGV when throwing my own exception #238

Closed
yyamano opened this issue Dec 2, 2016 · 3 comments
Closed

SIGSEGV when throwing my own exception #238

yyamano opened this issue Dec 2, 2016 · 3 comments

Comments

@yyamano
Copy link
Collaborator

yyamano commented Dec 2, 2016

I got SIGSEGV with the following config:

        location /foo {
            mruby_content_handler_code '
              class MyError < RuntimeError
              end
              raise MyError.new
            ';
        }
% curl http://localhost:58080/foo

This is gdb output.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000460e37 in ngx_vslprintf (buf=0x7fffffffd3a5 "", last=0x7fffffffdb40 "_\212:\034\271\277`\356(", fmt=0x7cbba7 "s", 
    args=0x7fffffffdb48) at src/core/ngx_string.c:256
256	                    while (*p && buf < last) {
Missing separate debuginfos, use: debuginfo-install glibc-2.17-106.el7_2.6.x86_64 nss-softokn-freebl-3.16.2.3-13.el7_1.x86_64 openssl-libs-1.0.1e-51.el7_2.5.x86_64 pcre-8.32-15.el7_2.1.x86_64 zlib-1.2.7-15.el7.x86_64
(gdb) bt
#0  0x0000000000460e37 in ngx_vslprintf (buf=0x7fffffffd3a5 "", last=0x7fffffffdb40 "_\212:\034\271\277`\356(", 
    fmt=0x7cbba7 "s", args=0x7fffffffdb48) at src/core/ngx_string.c:256
#1  0x0000000000459d80 in ngx_log_error_core (level=4, log=0xd97350, err=0, 
    fmt=0x7cbb68 "mrb_run failed: return 500 HTTP status code to client: error: %s") at src/core/ngx_log.c:135
#2  0x000000000054f1ef in ngx_mrb_raise_error (mrb=0xbceec0, obj=..., r=0xbcd4e0)
    at /home/vagrant/ngx_mruby/src/http/ngx_http_mruby_core.c:37
#3  0x000000000054977e in ngx_mrb_run (r=0xbcd4e0, state=0xbbc4a0, code=0xd06430, cached=1, result=0x0)
    at /home/vagrant/ngx_mruby/src/http/ngx_http_mruby_module.c:783
#4  0x000000000054d3e4 in ngx_http_mruby_content_inline_handler (r=0xbcd4e0)
    at /home/vagrant/ngx_mruby/src/http/ngx_http_mruby_module.c:1997
#5  0x00000000004ad5ed in ngx_http_core_content_phase (r=0xbcd4e0, ph=0xd18148) at src/http/ngx_http_core_module.c:1375
#6  0x00000000004ac0b7 in ngx_http_core_run_phases (r=0xbcd4e0) at src/http/ngx_http_core_module.c:845
#7  0x00000000004ac025 in ngx_http_handler (r=0xbcd4e0) at src/http/ngx_http_core_module.c:828
#8  0x00000000004bbbf0 in ngx_http_process_request (r=0xbcd4e0) at src/http/ngx_http_request.c:1914
#9  0x00000000004ba554 in ngx_http_process_request_headers (rev=0xbbc8e0) at src/http/ngx_http_request.c:1346
#10 0x00000000004b9937 in ngx_http_process_request_line (rev=0xbbc8e0) at src/http/ngx_http_request.c:1026
#11 0x00000000004b85a5 in ngx_http_wait_request_handler (rev=0xbbc8e0) at src/http/ngx_http_request.c:503
#12 0x000000000049bf3f in ngx_epoll_process_events (cycle=0xbb8500, timer=60000, flags=1)
    at src/event/modules/ngx_epoll_module.c:907
#13 0x000000000048aee1 in ngx_process_events_and_timers (cycle=0xbb8500) at src/event/ngx_event.c:242
#14 0x00000000004983ed in ngx_single_process_cycle (cycle=0xbb8500) at src/os/unix/ngx_process_cycle.c:309
#15 0x000000000045757b in main (argc=1, argv=0x7fffffffe408) at src/core/nginx.c:364
Breakpoint 1, ngx_mrb_raise_error (mrb=0xbceec0, obj=..., r=0xbcd4e0)
    at /home/vagrant/ngx_mruby/src/http/ngx_http_mruby_core.c:33
33	  obj = mrb_funcall(mrb, obj, "inspect", 0);
(gdb) p obj
$6 = {value = {f = 6.2755902132741798e-317, p = 0xc1d0f0, i = 12701936, sym = 12701936}, tt = MRB_TT_EXCEPTION}
(gdb) n
34	  if (mrb_type(obj) == MRB_TT_STRING) {
(gdb) p obj
$7 = {value = {f = 6.2755664981231794e-317, p = 0xc1d0c0, i = 12701888, sym = 12701888}, tt = MRB_TT_STRING}
(gdb) n
35	    str = mrb_str_ptr(obj);
(gdb) n
36	    err_out = str->as.heap.ptr;
(gdb) p str
$8 = (struct RString *) 0xc1d0c0
(gdb) p *str
$9 = {tt = MRB_TT_STRING, color = 4, flags = 720, c = 0xbd9440, gcnext = 0xc1d120, as = {heap = {len = 1229737545, aux = {
        capa = 977617999, shared = 0x4d203a343a45444f}, ptr = 0x726f72724579 <Address 0x726f72724579 out of bounds>}, 
    ary = "INLINE CODE:4: MyError\000"}}
@yyamano
Copy link
Collaborator Author

yyamano commented Dec 2, 2016

The following change fixes the problem, but can we expect that inspect method always returns null terminated string?

index 73f36df..37028d1 100644
--- a/src/http/ngx_http_mruby_core.c
+++ b/src/http/ngx_http_mruby_core.c
@@ -27,15 +27,10 @@ ngx_module_t ngx_http_mruby_module;
 
 void ngx_mrb_raise_error(mrb_state *mrb, mrb_value obj, ngx_http_request_t *r)
 {
-  struct RString *str;
-  char *err_out;
-
   obj = mrb_funcall(mrb, obj, "inspect", 0);
   if (mrb_type(obj) == MRB_TT_STRING) {
-    str = mrb_str_ptr(obj);
-    err_out = str->as.heap.ptr;
     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                  "mrb_run failed: return 500 HTTP status code to client: error: %s", err_out);
+                  "mrb_run failed: return 500 HTTP status code to client: error: %s", RSTRING_PTR(obj));
   }
 }

We might have the same problem in other places.

[vagrant@localhost src]$ grep -nR as.heap.ptr .
./stream/ngx_stream_mruby_module.c:293:    err_out = str->as.heap.ptr;
./stream/ngx_stream_mruby_module.c:306:    err_out = str->as.heap.ptr;
./stream/ngx_stream_mruby_module.c:650:    err_out = str->as.heap.ptr;
./http/ngx_http_mruby_core.c:45:    err_out = str->as.heap.ptr;
./http/ngx_http_mruby_core.c:58:    err_out = str->as.heap.ptr;
./http/ngx_http_mruby_module.c:2549:      err_out = str->as.heap.ptr;

@matsumotory
Copy link
Owner

Could you use %V syntax as ngx_str_t on ngx_log_error?

@yyamano
Copy link
Collaborator Author

yyamano commented Dec 2, 2016

I think "%*s" works too. See http://lxr.nginx.org/source/src/core/ngx_string.c#0091

Anyway, I'll take care of it, but not right now.

matsumotory added a commit that referenced this issue Dec 5, 2016
Use RSTRING_LEN() instead of as.heap.ptr to fix SIGSEGV. Fixed #238
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants