abbr / deasync

Turns async function into sync via JavaScript wrapper of Node event loop
MIT License
971 stars 73 forks source link

Segmentation fault (core dumped) #48

Open andresmgot opened 8 years ago

andresmgot commented 8 years ago

Hi there,

I was trying to execute this piece of code:

const net = require('net');
const deasync = require('deasync');
var reachable = false;
var cont = 0;
var retries = 4;
while (!reachable && cont < retries) {
  var done = false;
  var connection = net.connect({host: '127.0.0.1', port: 12123}, () => {
    done = true;
    reachable = true;
  });
  connection.on('error', () => {
    cont += 1;
    deasync.sleep(1000);
    done = true;
  });
  deasync.loopWhile(() => { return !done;});
  console.log('Retrying');
}

While the process is blocked in deasync.loopWhile, the deasync.sleep causes the mentioned core dumped. (Executed in Linux x64 with Node v4.2.2 and deasync v0.1.4). Placing the sleep after the loop works in the example but I wanted to let you know about the issue.

volure commented 7 years ago

I am having the same issue, however I have used deasync.sleep(100), as well as deasync(asyncFunction)

I am using ldapjs to grab a search and trying to deasync it.

original function

function findUserByEmail(email, callback){

  var client = ldapjs.createClient({
    url: ldapUri,
    timeout: 4000,
    connectTimeout: 2500
  });

  client.bind(ldapDn, ldapPass, function (err){ 
    if (err !== void 0 && err !== null){
      console.log("SearchErr:" + err);
    }
    else {
      var opts = { 
        filter: '&(mail=' + email + ')',
        scope: 'sub'
      };  
      client.search(ldapDnBase, opts, function(err, res) {
        if(err !== void 0 && err !== null){ 
          console.log("err:" + err);
        }   
        else {

          var output = [];

          res.on('searchEntry', function(entry) {
            output.push(entry.object);
          });
          res.on('searchReference', function(referral) {
            console.log('referral: ' + referral.uris.join());
          });
          res.on('error', function(err) {
            console.error('error: ' + err.message);
          });
          res.on('end', function(res) {
            console.log("End");
            //result.output = output;
            if (callback !== void 0){
              callback(err, output);
            }

            client.unbind(function (err){
              if (err !== void 0) {
                console.log("err:" + err);
              }
            });
            console.log('status: ' + res.status);
          });
        }

      });
    }
  });

}

Wrapped Function

   findUserByEmailSync = deasync(findUserByEmail);

Edited Function with manual deasync

function findUserByEmail(email, callback){

  var result = {done:false};

  var client = ldapjs.createClient({
    url: ldapUri,
    timeout: 4000,
    connectTimeout: 2500
  });

  client.bind(ldapDn, ldapPass, function (err){ 
    if (err !== void 0 && err !== null){
      console.log("SearchErr:" + err);
    }
    else {
      var opts = { 
        filter: '&(mail=' + email + ')',
        scope: 'sub'
      };  
      client.search(ldapDnBase, opts, function(err, res) {
        if(err !== void 0 && err !== null){ 
          console.log("err:" + err);
        }   
        else {

          var output = [];

          res.on('searchEntry', function(entry) {
            output.push(entry.object);
          });
          res.on('searchReference', function(referral) {
            console.log('referral: ' + referral.uris.join());
          });
          res.on('error', function(err) {
            console.error('error: ' + err.message);
          });
          res.on('end', function(res) {
            console.log("End");
            //result.output = output;
            if (callback !== void 0){
              callback(err, output);
            }

            result.output = output;

            client.unbind(function (err){
              if (err !== void 0) {
                console.log("err:" + err);
              }
            });
            console.log('status: ' + res.status);
            result.done = true;
          });
        }

      });
    }
  });

  if (callback === void 0 || callback == null){
    while (result.done == false){
      deasync.sleep(100);
    }
    return result.output;
  }

}

Functional Call. No Segfault

      var result = ldap.findUserByEmail(body.email, function (err, result){

          if (result !== void 0){ 
            console.log("Found Email:" + JSON.stringify(result, null, 2));

          }   
          //console.log("###### ERROR    ######\n" + JSON.stringify(err, null, 2));
          //console.log("###### ACTIVATE ######\n" + JSON.stringify(body, null, 2));
          res.redirect(path.join(req.baseUrl, "home"));
        }); 

Broken Call Segfault

      var result = ldap.findUserByEmail(body.email);
      if (result !== void 0){
         console.log("Found Email:" + JSON.stringify(result, null, 2));
      }

Broken Call Segfault

      var result = ldap.FindUserByEmailSync(body.email);
      if (result !== void 0){
         console.log("Found Email:" + JSON.stringify(result, null, 2));
      }

Segmentation Fault Output

PID 6979 received SIGSEGV for address: 0x30
/projects/thisproject/node_modules/segfault-handler/build/Release/segfault-handler.node(+0x1a9b)[0x7fe42aac3a9b]
/lib64/libpthread.so.0(+0xf370)[0x7fe42d09a370]
node(SSL_read+0x0)[0x8e6dc0]
node(_ZN4node7TLSWrap8ClearOutEv+0x5d)[0x12ed72d]
node(_ZN4node7TLSWrap10OnReadImplElPK8uv_buf_t14uv_handle_typePv+0xae)[0x12ede8e]
node(_ZN4node10StreamWrap6OnReadEP11uv_stream_slPK8uv_buf_t+0x7c)[0x12bbfdc]
node[0x151296f]
node[0x1512fd0]
node[0x15189c8]
node(uv_run+0x156)[0x1508d16]
node(_ZN4node5StartEP9uv_loop_siPKPKciS5_+0x6ff)[0x126f2af]
node(_ZN4node5StartEiPPc+0xa3)[0x126e7e3]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fe42ccebb35]
node[0x8bc541]
volure commented 7 years ago

Update, I adapted my project to use the loopwhile function, and it is still performing segfault

here is the code I changed

  if (callback === void 0 || callback == null){
    deasync.loopWhile(() => { return !result.done;});

    return result.output;
  }

also, if I comment the deasync loop code, the segfault does not occur, however it obviously does not function.

volure commented 7 years ago

I took the deasync code out of an existing async callback, and deasync'd the entire call rather than a subset of the calls.

Seemed to have done the trick, but not completely ideal.

RamprasadAkella commented 7 years ago

@abbr Can you please let me know are you working on this ? I am also facing a similar issue.