C API mysql_real_connect node-gyp 构建时抛出分段错误(核心转储)

C API mysql_real_connect throw Segmentation fault (core dumped) when it is build by node-gyp

提问人:Jonah 提问时间:11/1/2023 最后编辑:Jonah 更新时间:11/1/2023 访问量:73

问:

问题

当它直接使用 g++ 编译时,我可以运行该函数。但是当它使用node-gyp构建时,我无法运行它。我能够将我的问题缩小到几个文件,我希望你们中的一些人能让我离开这里。提前致谢:-)dosomething()

我观察到:

  • 当 host= 时,使用localhostnode-gyp
  • 当 host= 或 时,使用localhostexternal IPg++ -o conn $(mysql_config --cflags) test_db_conn.cpp -std=c++17 $(mysql_config --libs)
  • 没有错误代码,只有Segmentation fault

我做了:

  • 设置bind-address=0.0.0.0
  • 将目标主机添加到 /etc/hosts(我能够从终端连接到主机数据库)并将其称为“jonah”,我能够 ping 并使用“jonah”执行程序host

我敢肯定:

  • 凭据中使用的任何字符都不需要转义

环境:

  • 操作系统: Ubuntu 22.04.02 LTS (server)
  • 节点:v16.20.0
  • 节点-gyp:^9.4.0
  • MySQL:版本 8.0.35-0ubuntu0.22.04.1
  • MySQL C API:版本 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++"]
                }
            ]
        }
    ]
}
C++ C++17 mysql连接器 -gyp节点 插件API

评论

1赞 Ted Lyngmo 11/1/2023
如果您正在使用或尝试编译并重新运行您的程序。它可能会提供有关问题所在位置的其他线索。gccclang-g -fsanitize=address,undefined
0赞 Jonah 11/1/2023
不,我使用的是 g++。反正我还是试一试,它不会编译返回undefined reference to symbol '_ZTIPKc@@CXXABI_1.3'
0赞 Ted Lyngmo 11/1/2023
这个残缺不全的名字意味着你是否在程序的某个地方使用了运算符?typeinfo for char const*<typeinfo>typeid
1赞 Ted Lyngmo 11/1/2023
我并不是说你应该用 gcc 编译。我的意思是工具链中的gcc。用g++ -g -fsanitize=address,undefined ...
1赞 drescherjm 11/2/2023
这不应该解决它应该帮助你找到错误的问题:https://www.osc.edu/resources/getting_started/howto/howto_use_address_sanitizer#:~:text=The%20%22%2Dfsanitize%3Daddress%22,also%20statically%20link%20against%20Asan。

答: 暂无答案