SAP / node-rfc

Asynchronous, non-blocking SAP NW RFC SDK bindings for Node.js
Apache License 2.0
252 stars 73 forks source link

App crashes with `double free or corruption (fasttop) Aborted (core dumped)` #269

Closed iamNoah1 closed 1 year ago

iamNoah1 commented 2 years ago

Describe the bug App that used node-rf crashes with double free or corruption (fasttop) Aborted (core dumped)

To Reproduce Installed by adding to package.json + npm install

No specific steps. The app just crashes after doing some RFC Calls against SAP.

Environment

platform: { name: 'linux', arch: 'x64', release: '5.4.0-1085-aws' },
  env: { SAPNWRFC_HOME: '', RFC_INI: '' },
  versions: {
    node: '16.17.0',
    v8: '9.4.146.26-node.22',
    uv: '1.43.0',
    zlib: '1.2.11',
    brotli: '1.0.9',
    ares: '1.18.1',
    modules: '93',
    nghttp2: '1.47.0',
    napi: '8',
    llhttp: '6.0.7',
    openssl: '1.1.1q+quic',
    cldr: '41.0',
    icu: '71.1',
    tz: '2022a',
    unicode: '14.0',
    ngtcp2: '0.1.0-DEV',
    nghttp3: '0.1.0-DEV'
  },
  noderfc: {
    version: '2.7.0',
    nwrfcsdk: { major: 7500, minor: 0, patchLevel: 8 }
  }
}

Additional context

Same behavior when running app inside node:lts docker image.

bsrdjan commented 2 years ago

Hello @iamNoah1, could you please upgrade the SAP NWRFC SDK to PL10 and share the script to reproduce the issue?

iamNoah1 commented 1 year ago

Hi @bsrdjan, thanks for the hint. I patched the SDK, but the bug still appears. Hard to give a script that you could execute to reproduce the bug on your own, as it is an application that I cannot expose entirely.

However, I tried to extract the relevant parts. Let me know if this is sufficient or if I need to provide further information.

const sapService = require('./sap.service');

@Controller('/api/v2/SapConn/')
export class AppController {
  @Post(':clientId/:systemId/:rfcFunctionName')
  @HttpCode(200)
  async makeRfcCallToSAP(
    @Param('clientId') clientId: string,
    @Param('systemId') systemId: string,
    @Param('rfcFunctionName') rfcFunctionName: string,
    @Body() payload: unknown,
  ): Promise<string> {
    const config = await this.getConfig(clientId, systemId);

    try {
      const response = await sapService.makeRfcCallToSAP(
        config,
        rfcFunctionName,
        payload,
      );
      return response;
    } catch (error) {
      throw new InternalServerErrorException(error);
    }
  }

....

//sap.service
module.exports.makeRfcCallToSAP = async function (
    connectionConfig,
    rfcFunctionName,
    payload,
  ) {
    const pool = new noderfc.Pool({
      connectionParameters: connectionConfig,
      clientOptions,
    });
    const client = await pool.acquire();

    const sapResponse = await client.call(
      rfcFunctionName,
      payload),
    );

    return handleSAPResponse(sapResponse);
  };

Thanks for your efforts.

iamNoah1 commented 1 year ago

friendly ping @bsrdjan

bsrdjan commented 1 year ago

Hello @iamNoah1,

Could it be that issue is related to concurrent POST requests? If yes, how many in parallel and which http server is used? I could try to reproduce.

I am not sure how AppController threading works but can try to move pool instantiation outside of makeRfcCallToSAP() and use the single pool instance ?

Per example code, for each post request the makeRfcCallToSAP() is called and it creates new pool instance, from which the node-rfc client is acquired. The flow is like without pool because pool instances are not automatically synchronised and application must ensure single pool consumes SAP RFC SDK at the time.

Can you try to use one single pool instance and in makeRfcCallToSAP() acquire the client from that instance, make the call and release the client.

iamNoah1 commented 1 year ago

Hi @bsrdjan,

thanks for the reply. I am not doing that much requests in parallel, maybe 2-3. but what you say makes totally sense, my feeling said that it might have something todo the pool/the way we create the connections. I will try your suggestion and let you know if it worked out.

iamNoah1 commented 1 year ago

I guess that solved the problem, many thanks for the support :)