From: Nathaniel Talbott Date: 2003-11-10T22:29:34+09:00 Subject: Re: Segfault in Ruby/ODBC Nathaniel Talbott [mailto:nathaniel@NOSPAMtalbott.ws] wrote: > My program is causing a segfault under load, and while I'm > going to dig in to figuring out why, I thought I'd go ahead > and see if anyone here could give me a hand. It appears that > the Ruby/ODBC extension is somehow behaving badly, and not > being a C guy, I'd appreciate any help you can give me. > > The backtrace below was generated off of an optimized ruby > without debugging info... I may be able to do it again and > get better information, but not immediately. Also, the > program itself is large and proprietary, and as with most > SEGFAULTs, I can't reproduce the problem except with the full > program under load. OK, I have better data now. First of all, I have a small program that will reproduce the problem, provided you have access to an odbc database: require 'dbi' threads = [] Thread.abort_on_exception = true 10.times do |i| threads << Thread.new do db = DBI::connect("dbi:ODBC:dbname", "user", "password") loop do p "Looping #{i}..." db.tables db.execute("SELECT COUNT(*) FROM table").finish db.tables db.execute("SELECT * FROM table").finish end end end threads.each{|t| t.join} Obviously you'd need to replace dbname, user, password and table with things that make sense for your setup. I'm using unixODBC to connect via FreeTDS to a MSSQL server on a Windows NT box. Also, I've recompiled Ruby and the odbc driver with debugging information, and have a better backtrace: (gdb) run Starting program: /usr/bin/ruby t.rb [New Thread 16384 (LWP 16080)] "Looping 0..." "Looping 2..." "Looping 1..." Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 16384 (LWP 16080)] 0x400de1f5 in mallopt () from /lib/libc.so.6 (gdb) bt #0 0x400de1f5 in mallopt () from /lib/libc.so.6 #1 0x400dd383 in malloc () from /lib/libc.so.6 #2 0x08070cf6 in ruby_xmalloc (size=16) at gc.c:108 #3 0x080bf370 in st_init_table_with_size (type=0x81000dc, size=11) at st.c:167 #4 0x080bf3c8 in st_init_table (type=0x81000dc) at st.c:180 #5 0x08073c87 in hash_alloc (klass=1075592068) at hash.c:188 #6 0x08073cb8 in rb_hash_new () at hash.c:196 #7 0x4022ec69 in do_fetch (q=0x819d6d0, mode=1) at odbc.c:3802 #8 0x4022fce4 in stmt_fetch_hash1 (argc=1, argv=0xbfffabb0, self=1075690112, bang=0) at odbc.c:4206 #9 0x40230106 in stmt_each_hash (argc=0, argv=0x0, self=1075690112) at odbc.c:4345 #10 0x0806adb3 in call_cfunc (func=0x40230030 , recv=1075690112, len=-1, argc=0, argv=0x0) at eval.c:4841 #11 0x0805dc43 in rb_call0 (klass=1075735712, recv=1075690112, id=14073, oid=14073, argc=0, argv=0x0, body=0x401e2164, nosuper=0) at eval.c:4975 #12 0x0805e788 in rb_call (klass=1075735712, recv=1075690112, mid=14073, argc=0, argv=0x0, scope=0) at eval.c:5196 #13 0x0805866a in rb_eval (self=1075693732, n=0x401f75a0) at eval.c:3026 #14 0x08057438 in rb_eval (self=1075693732, n=0x401f7a78) at eval.c:2753 #15 0x08057979 in rb_eval (self=1075693732, n=0x401f6204) at eval.c:2839 #16 0x0805e23f in rb_call0 (klass=1075705512, recv=1075693732, id=10217, oid=10217, argc=0, argv=0x0, body=0x401f6204, nosuper=0) at eval.c:5103 #17 0x0805e788 in rb_call (klass=1075705512, recv=1075693732, mid=10217, argc=0, argv=0x0, scope=0) at eval.c:5196 #18 0x0805866a in rb_eval (self=1075695672, n=0x401ab2dc) at eval.c:3026 #19 0x0805e23f in rb_call0 (klass=1075842852, recv=1075695672, id=10217, oid=10217, argc=0, argv=0x0, body=0x401ab2dc, nosuper=0) at eval.c:5103 #20 0x0805e788 in rb_call (klass=1075842852, recv=1075695672, mid=10217, argc=0, argv=0x0, scope=0) at eval.c:5196 #21 0x0805866a in rb_eval (self=1075620448, n=0x401baf98) at eval.c:3026 #22 0x0805c050 in rb_yield_0 (val=6, self=1075620448, klass=0, flags=0, avalue=0) at eval.c:4229 #23 0x0805c432 in rb_f_loop () at eval.c:4330 #24 0x0806adcd in call_cfunc (func=0x805c418 , recv=1075620448, len=0, argc=0, argv=0x0) at eval.c:4844 #25 0x0805dc43 in rb_call0 (klass=1075625128, recv=1075620448, id=3921, oid=3921, argc=0, argv=0x0, body=0x401ca1a0, nosuper=0) at eval.c:4975 #26 0x0805e788 in rb_call (klass=1075625128, recv=1075620448, mid=3921, argc=0, argv=0x0, scope=1) at eval.c:5196 #27 0x08058924 in rb_eval (self=1075620448, n=0x401bad7c) at eval.c:3041 #28 0x08057438 in rb_eval (self=1075620448, n=0x401bad04) at eval.c:2753 #29 0x0805c050 in rb_yield_0 (val=1075838972, self=1075620448, klass=0, flags=2, avalue=2) at eval.c:4229 #30 0x08068e60 in rb_thread_yield (arg=1075838972, th=0x816efd8) at eval.c:9581 #31 0x08068b04 in rb_thread_start_0 (fn=0x8068d94 , arg=0x401ffffc, th=0x816efd8) at eval.c:9495 #32 0x08068f53 in rb_thread_initialize (thread=1075839612, args=1075838972) at eval.c:9610 #33 0x0806ad94 in call_cfunc (func=0x8068f04 , recv=1075839612, len=-2, argc=0, argv=0x0) at eval.c:4838 #34 0x0805dc43 in rb_call0 (klass=1075609928, recv=1075839612, id=2953, oid=2953, argc=0, argv=0x0, body=0x401c80e4, nosuper=0) at eval.c:4975 #35 0x0805e788 in rb_call (klass=1075609928, recv=1075839612, mid=2953, argc=0, argv=0x0, scope=1) at eval.c:5196 #36 0x0805e9ba in rb_funcall2 (recv=1075839612, mid=2953, argc=0, argv=0x0) at eval.c:5271 #37 0x0806124c in rb_obj_call_init (obj=1075839612, argc=0, argv=0x0) at eval.c:6341 #38 0x08068eb4 in rb_thread_s_new (argc=0, argv=0x0, klass=1075609928) at eval.c:9594 #39 0x0806adb3 in call_cfunc (func=0x8068e74 , recv=1075609928, len=-1, argc=0, argv=0x0) at eval.c:4841 #40 0x0805dc43 in rb_call0 (klass=1075609908, recv=1075609928, id=3353, oid=3353, argc=0, argv=0x0, body=0x401c810c, nosuper=0) at eval.c:4975 #41 0x0805e788 in rb_call (klass=1075609908, recv=1075609928, mid=3353, argc=0, argv=0x0, scope=0) at eval.c:5196 #42 0x0805866a in rb_eval (self=1075620448, n=0x401bb254) at eval.c:3026 #43 0x08057438 in rb_eval (self=1075620448, n=0x401bacf0) at eval.c:2753 #44 0x08058506 in rb_eval (self=1075620448, n=0x401bacb4) at eval.c:3021 #45 0x0805c050 in rb_yield_0 (val=1, self=1075620448, klass=0, flags=0, avalue=0) at eval.c:4229 #46 0x0805c306 in rb_yield (val=1) at eval.c:4282 #47 0x08087af3 in int_dotimes (num=21) at numeric.c:1775 #48 0x0806adcd in call_cfunc (func=0x8087aac , recv=21, len=0, argc=0, argv=0x0) at eval.c:4844 #49 0x0805dc43 in rb_call0 (klass=1075606888, recv=21, id=5385, oid=5385, argc=0, argv=0x0, body=0x401c74a0, nosuper=0) at eval.c:4975 #50 0x0805e788 in rb_call (klass=1075606888, recv=21, mid=5385, argc=0, argv=0x0, scope=0) at eval.c:5196 #51 0x0805866a in rb_eval (self=1075620448, n=0x401bb2e0) at eval.c:3026 #52 0x08057438 in rb_eval (self=1075620448, n=0x401bb3bc) at eval.c:2753 #53 0x08053a80 in eval_node (self=1075620448, node=0x401bb3bc) at eval.c:1217 #54 0x0805408a in ruby_exec () at eval.c:1387 #55 0x0805410d in ruby_run () at eval.c:1408 #56 0x08051f93 in main (argc=2, argv=0xbffff704, envp=0xbffff710) at main.c:50 (gdb) c Continuing. /usr/lib/ruby/site_ruby/1.8/DBD/ODBC/ODBC.rb:124: [BUG] Segmentation fault ruby 1.8.1 (2003-10-31) [i386-linux] Program received signal SIGABRT, Aborted. 0x400955f1 in kill () from /lib/libc.so.6 I'm going to dig in to this and see if I can figure out what the problem is, but any help would be appreciated. Let me know if there's any more information I can provide that would be useful. Thanks, Nathaniel <:((><