core dumps using double callback with JDBC (+ workaround) #24

Closed
johnno1962 opened this Issue Dec 1, 2012 · 0 comments

Comments

Projects
None yet
1 participant
@johnno1962

Hi,

excellent piece of work! I've been getting frequent core dumps however with a particular jdbc snippet with the "npm" version of node-java. In the end I found that a small change (below) to remove the second callback within a callback seems to make the problem go away. Anyway, building from the github source directly the problem is resolved.

// Load the http module to create an http server.
var http = require('http');
var util = require("util");
var java = require("java");
java.options.push("-Djava.awt.headless=true"); // running on OS X 10.8
java.classpath.push("../jtds-1.2.7-dist/jtds-1.2.7.jar");

var cl = java.callStaticMethodSync("java.lang.ClassLoader","getSystemClassLoader")
cl.loadClassSync( "net.sourceforge.jtds.jdbc.Driver" ).newInstanceSync();

var i = 0;

function fetch(sql,cb) {
    var cn = java.callStaticMethodSync("java.sql.DriverManager","getConnection",
    "jdbc:jtds:sybase://172.16.54.129:5000;charset=iso_1;", "sa", "" );
    var s = cn.createStatementSync();

    s.execute( sql, function(err,ok) {
        if ( err )
            console.error(err);
        else
            s.getResultSet( function(err,rs) {
                var md = rs.getMetaDataSync();
                var cc = md.getColumnCountSync();
                var rows = [[]];

                for (var c=0 ; c<cc ; c++)
                    rows[0].push(md.getColumnLabelSync(c+1))

                while( rs.nextSync() ) {
                    var row = [];
                    for (var c=0 ; c<cc ; c++)
                        row.push(rs.getStringSync(c+1));
                    rows.push(row);
                }

                cn.closeSync();
                cb(rows);
            } )
    } );
}

// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "text/html"});
  response.write("Hello World "+i+++'<pre>'+util.inspect(request.headers)+"\n");
  fetch( "waitfor delay '00:00:05' select * from pubs2..titles",
    function(rows) {
        var html = '<table>';
        for ( var r=0 ; r<rows.length ; r++ ) {
            html += '\n<tr>';
            for ( var c=0 ; c<rows[r].length ; c++ )
                html += (r==0?'<th>':'<td>')+rows[r][c];
        }
        response.write(html+'\n</table>');
        response.end();
    }
  );
} );

// Listen on port 8000, IP defaults to 127.0.0.1
server.listen(8000);

// Put a friendly message on the terminal
console.log("Server running at http://127.0.0.1:8000/");

Server running at http://127.0.0.1:8000/
Reading symbols for shared libraries . done
Invalid memory access of location 0x1 rip=0x104c9ead3

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000001
0x0000000104c9ead3 in JVM_FindPrimitiveClass ()
(gdb) where
#0  0x0000000104c9ead3 in JVM_FindPrimitiveClass ()
#1  0x0000000104cabbc4 in JVM_InternString ()
#2  0x0000000104cabb4f in JVM_InternString ()
#3  0x0000000100bca66a in JNIEnv_::NewGlobalRef (this=0x1060011d0, lobj=0x10db06350) at jni.h:836
#4  0x0000000100bd1a04 in MethodCallBaton::MethodCallBaton (this=0x101818cc0, java=0x101a010f0, method=0x10db06350, args=0x10db06308, callback=@0x7fff5fbfeea8) at methodCallBaton.cpp:12
#5  0x0000000100bd327d in InstanceMethodCallBaton::InstanceMethodCallBaton (this=0x101818cc0, java=0x101a010f0, obj=0x100a12e20, method=0x10db06350, args=0x10db06308, callback=@0x7fff5fbfeea8) at methodCallBaton.cpp:188
#6  0x0000000100bcd83e in JavaObject::methodCallSync (args=@0x7fff5fbff070) at javaObject.cpp:163
#7  0x0000000100145918 in HandleApiCallHelper [inlined] () at :1145
#8  0x0000000100145918 in Builtin_HandleApiCall (isolate=0x101010400) at ../deps/v8/src/builtins.cc:1162
#9  0x0000092097b0618e in ?? ()
#10 0x0000092097b8d1c8 in ?? ()
#11 0x0000092097b248c7 in ?? ()
#12 0x0000092097b11317 in ?? ()
#13 0x000000010017106d in Invoke (is_construct=, argc=2, args=0x7fff5fbff360, has_pending_exception=0x7fff5fbff317) at ../deps/v8/src/execution.cc:118
#14 0x000000010012108c in v8::Function::Call (this=0x1020041a0, argc=2, argv=0x7fff5fbff360) at ../deps/v8/src/api.cc:3644
#15 0x0000000100bd2367 in MethodCallBaton::after (this=0x100e08290, env=0x1060011d0) at methodCallBaton.cpp:62
#16 0x0000000100bd1ae8 in MethodCallBaton::EIO_AfterMethodCall (req=0x100e082e0) at methodCallBaton.cpp:46
#17 0x000000010004e5ff in uv__after_work (eio=) at ../deps/uv/src/unix/fs.c:669
#18 0x0000000100046a21 in eio_finish (req=0x100e09ae0) at ../deps/uv/src/unix/eio/eio.c:860
#19 0x0000000100044df3 in etp_poll [inlined] () at :698
#20 0x0000000100044df3 in eio_poll (channel=) at ../deps/uv/src/unix/eio/eio.c:966
#21 0x0000000100053a1f in uv_eio_want_poll_notifier_cb (watcher=, status=100667856) at ../deps/uv/src/unix/uv-eio.c:46
#22 0x0000000100043e1a in uv__async_io (loop=, handle=0x1060011d0, events=2) at ../deps/uv/src/unix/async.c:117
#23 0x000000010004974c in ev_invoke_pending (loop=0x100639af8) at ../deps/uv/src/unix/ev/ev.c:2145
#24 0x0000000100044110 in uv__run (loop=0x1006391b0) at ../deps/uv/src/unix/core.c:248
#25 0x000000010004403f in uv_run (loop=0x1006391b0) at ../deps/uv/src/unix/core.c:265
#26 0x0000000100009191 in node::Start (argc=, argv=0x7fff5fbffa98) at ../src/node.cc:2974
#27 0x0000000100001174 in start ()
(gdb) 

If I change the fetch code to only have a single callback it is perfectly reliable:

function fetch(sql,cb) {
    var cn = java.callStaticMethodSync("java.sql.DriverManager","getConnection",
    "jdbc:jtds:sybase://172.16.54.129:5000;charset=iso_1;", "sa", "" );
    var s = cn.createStatementSync();

    s.execute( sql, function(err,ok) {
        if ( err )
            console.error(err);
        else {
            var rs = s.getResultSetSync()
            var md = rs.getMetaDataSync();
            var cc = md.getColumnCountSync();
            var rows = [[]];

            for (var c=0 ; c<cc ; c++)
                rows[0].push(md.getColumnLabelSync(c+1))

            while( rs.nextSync() ) {
                var row = [];
                for (var c=0 ; c<cc ; c++)
                    row.push(rs.getStringSync(c+1));
                rows.push(row);
            }

            cn.closeSync();
            cb(rows);
        }
    } );
}

Hope this helps track something down.

John

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