Issue
I could run the function dosomething()
when it is compiled with g++ directly. But I could not run it when it is build with node-gyp. I was able to narrow my issue down to just a few files, I am hoping that some of you can get me out from here. Thanks in advance :-)
I observed:
- when host=
localhost
, execute successfully when build withnode-gyp
- when host=
localhost
orexternal IP
, execute successfully when build withg++ -o conn $(mysql_config --cflags) test_db_conn.cpp -std=c++17 $(mysql_config --libs)
- no error code, only
Segmentation fault
I did:
- set
bind-address=0.0.0.0
- add target host to /etc/hosts (I am able to connect to the host DB from the terminal) and call it "jonah", I was able to ping and execute the program with the "jonah" as
host
I am certain:
- None of the characters used in the credential needs to be escaped
Environment:
- OS: Ubuntu 22.04.02 LTS (server)
- Node: v16.20.0
- node-gyp: ^9.4.0
- MySQL: Ver 8.0.35-0ubuntu0.22.04.1
- MySQL C API: Ver 8
// test_db_conn.cpp
/**
*
* g++ -o conn $(mysql_config --cflags) test_db_conn.cpp -std=c++17
* $(mysql_config --libs)
*
*/
#include <mysql.h>
#include <cstring>
#include <iostream>
void dosomething();
int main() {
dosomething();
return 0;
}
void dosomething() {
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row;
constexpr int QUERY_STATEMENT_LEN = 512;
char query[QUERY_STATEMENT_LEN] = {0}, *end_pos = nullptr;
long lTime = 0;
std::string stmt = "SELECT MIN(time) FROM Log";
std::cout << stmt << '\n';
try {
end_pos = stpcpy(query, stmt.c_str());
conn = mysql_init(NULL);
const char *host = "IP"; // 172.x.x.x
const char *user = "username";
const char *password = "password";
const char *database = "dbname";
const int port = 3306;
if (!mysql_real_connect(conn, host, user, password, database, port, NULL, 0)) {
throw mysql_error(conn);
}
if (mysql_real_query(conn, query, (unsigned int)(end_pos - query))) {
throw mysql_error(conn);
}
res = mysql_use_result(conn);
while ((row = mysql_fetch_row(res)) != NULL) {
if (row[0] == NULL) break;
lTime = std::stol(row[0]);
break;
}
// release resources
mysql_free_result(res);
mysql_close(conn);
std::cout << "ltime " << lTime << '\n';
} catch (const char *e) {
if (res) mysql_free_result(res);
if (conn) mysql_close(conn);
std::cerr << "e " << e << '\n';
throw e;
}
}
// CMySQL.h
#ifndef CMYSQL_H
#define CMYSQL_H
#include <mysql.h> // find /usr/ -type f -name mysql.h
#include <node.h> // find /usr/ -type f -name node.h
#include <node_object_wrap.h>
#include <cstring>
#include <exception>
#include <iostream>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "DBCredential.h"
class CMySQL : public node::ObjectWrap {
private:
DBCredential m_db;
void dosomething();
public:
explicit CMySQL(const DBCredential db) : m_db(db) {}
~CMySQL() {}
static void Init(v8::Local<v8::Object> exports);
static void New(const v8::FunctionCallbackInfo<v8::Value> &args);
static void pull(const v8::FunctionCallbackInfo<v8::Value> &args);
};
#endif
// binding.gyp
{
"targets":[
{
"target_name": "CMySQL_Addon",
"sources": [
"./DBCredential.cc",
"./CMySQL.cc",
"./MySQL_Addon.cc"
],
"cflags_cc":[
"-fexceptions",
"-std=c++17"
],
"cflags": [
"-I/usr/include/mysql"
],
"libraries": [
"-L/usr/lib/x86_64-linux-gnu",
"-lmysqlclient",
"-lzstd",
"-lssl",
"-lcrypto",
"-lresolv",
"-lm",
"-lz"
],
"make_global_settings": [
{
"CC": ["/usr/bin/g++"]
}
]
}
]
}