wankdanker / node-odbc

ODBC bindings for node
MIT License
174 stars 79 forks source link

Segmentation fault (core dumped) causing app crash on .query and .querySync #46

Open martin-kieliszek opened 5 years ago

martin-kieliszek commented 5 years ago

Hi, I am getting a Segmentation fault (core dumped) after this odbc library executes a heavy (potentially bad performing query) sql string on self.conn.query(sql, cbQuery); command (eg. line 260 of ./lib/odbc.js and line 336 to name a couple). The fault occurs within milliseconds.

Immediate question: How do you recommend I obtain error logs from the cpp binding so that I can provide more information?

Further information: From what I have experienced so far, this only occurs on particular SQL query strings that are passed into self.conn.query(sql,cbQuery).

Very simple queries - whether they are syntactically incorrect or perfect, have no problem executing towards the target Postgres DB. (Eg. if wrong syntax is passed through the binding, the DB correctly responds back with error messages).

However, a larger query like the one shown below causes a segmentation fault (without the ability for my app to gracefully catch an exception from the cpp binding, inform the user that an error has occured or otherwise fail nicely prior to fault) - it just tears down the entire process within milliseconds.

SQL Query example showing what leads to an seg fault. Hopefully this can help you and I understand what resides within the below string that could cause a segmentation fault in the underlying odbc_binding cpp code

WITH sample_set AS (
  SELECT 
    sample.SERVICE_ID
    , sample.SERVICE_NAME
    , sample.SERVICE_PRICE
    , sample.SERVICE_ORDERED_DATE_TS
    FROM EXAMPLE_SCHEMA_NAME.SERVICE_TABLE sample 
    JOIN (
      SELECT ID
      , COUNT(*) count 
      FROM EXAMPLE_SCHEMA_NAME.SERVICE_TABLE 
      WHERE SERVICE_NAME in (
        SELECT ORDER_SERVICE_NAME
        FROM EXAMPLE_SCHEMA_NAME.SERVICE_ORDER_HISTORY_TIMELINE 
        WHERE ORDER_TYPE='Upgrade' 
        AND ORDERED_DATE > now() - interval '1 day' 
        ORDER BY ORDERED_DATE DESC LIMIT 1
      ) 
      GROUP BY SERVICE_NAME HAVING COUNT(*) > 2
    ) sample on sample.SERVICE_NAME = multiple_service_upgrade_history.SERVICE_NAME
),
numbered_results AS
( SELECT *
  ROW_NUMBER() OVER (PARTITION BY sample_set.SERVICE_NAME ORDER BY sample_set.SERVICE_ORDERED_DATE_TS DESC) AS rownum
  FROM sample_set 
)
SELECT numbered_results.*
FROM numbered_results
WHERE numbered_results.rownum < 3

I won't explain the context of the above query - I have simply presented the precise query structure that causes an Segmentation fault.

I am hoping this issue will help find a new exception to raise within the library such that an error message can be returned to the JS lib

martin-kieliszek commented 5 years ago

In the interim, I am attempting to take steps forward to understand what is happening.

I am setting up a gdb debugger to listen on the odbc_bindings.node file that resides within the Release/build directory.

eg.

$ gdbserver localhost:4444 ./node_modules/odbc/Release/build/odbc_bindings.node
Process ./odbc_bindings.node created; pid = 22016
Listening on port 4444

With .vscode launch.json settings:

 {
            "name": "C++ Remote Debug",
            "type": "cppdbg",
            "request": "launch",
            "miDebuggerServerAddress": "localhost:4444",
            "program": "${workspaceFolder}/node_modules/odbc/build/Release/odbc_bindings.node",
            "cwd": ".", 
            "linux": {
                "MIMode": "gdb"
            },
            "osx": {
                "MIMode": "lldb"
            },
            "windows": {
                "MIMode": "gdb"
            }
        }

No luck thus far getting any insight

If anyone can provide other debug recommendations, would appreciate your comments.

Happy to follow up this issue with slight direction on environment setup

martin-kieliszek commented 5 years ago

Seg fault appears to be the result of a missing , within the second AS clause

( SELECT *
  ROW_NUMBER() 

should be

( SELECT *
  , ROW_NUMBER()

Did further testing - Segmentation fault also occurs if a missing , exists between both AS statements.

Other information - also occurs if I run the library and code within another environment such as a docker container with os:

# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=debian
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

FYI node-odbc version is 1.4.5

Have rebuilt manually within node_modules aswell using make all to ensure everything is all good. Still occuring.

Hope the above information can assist in identifying why there may be a seg fault. Memory issue on SQL validation?

asztal commented 5 years ago

Have you considered that it might be crashing in the psqlodbc driver itself, or in unixODBC somewhere?

If you enable core dumps you might be able to use gdb to get a stack trace from the core dump, which may at least tell you what the segfaulting module is.