Mysql的Debug模式实现_MySQL
Mysql的Debug模式实现
前一段领导开发了一个内核的模块,测试的过程中,发现导致MYSQL客户端无法连接服务器。
经过查询文档,追根溯源,终于找到了MYSQL实现链接客户端的代码,在源文件sql-common/client.c里的 CLI_MYSQL_REAL_CONNECT 函数。
但是代码很长,一时半会儿肯定看不明白。这个时候发现,发现代码当中有很多这样的代码:
[cpp]
DBUG_ENTER("mysql_real_connect");
说明只要以调试模式启动MYSQL,就可以跟踪代码的执行。
经过查询文档和测试,只要在 cmake 的时候,增加参数 cmake -WITH_DEBUG=1 就可以了。
然后启动一个MYSQL客户端程序之前,更改一个环境变量:
[plain]
export MYSQL_DEBUG=d:t:O,/tmp/client.trace
使用编辑器打开 /tmp/client.trace 就会得到这样的Debug信息:
[cpp]
| info: Connect socket
| >vio_socket_connect
| | >vio_set_blocking
| | | | >vio_io_wait | | | | >vio_set_blocking | | | | info: No success, close socket, try next address. | info: End of connect attempts, sock: 4 status: 1 error: 0 | error: Got error 0 on connect to 'localhost' | >set_mysql_extended_error | | enter: error :2003 'Can't connect to MySQL server on '%-.100s' (%d)' | | error: message: 2003/HY000 (Can't connect to MySQL server on 'localhost' (0)) 后面的数字是行号。从这个文件就可以追踪程序的执行啦! 好牛逼啊!我们不禁感叹。之余,学习了一下这个调试模式的具体实现: 在 CMakeList.txt 中,有这么一段代码: [plain] IF(WITH_DEBUG) SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING ${BUILDTYPE_DOCSTRING} FORCE) [plain] IF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_GENERATOR MATCHES "Visual Studio" AND NOT CMAKE_GENERATOR MATCHES "Xcode") # This is the case of no CMAKE_BUILD_TYPE choosen, typical for VS and Xcode # or if custom C flags are set. In VS and Xcode for non-Debug configurations # DBUG_OFF is already correctly set. Use DBUG_OFF for Makefile based projects # without build type too, unless user specifically requests DBUG. IF(NOT CMAKE_C_FLAGS MATCHES "-DDBUG_ON") ADD_DEFINITIONS(-DDBUG_OFF) ENDIF() ENDIF() 如果没有设置 CMAKE_BUILD_TYPE ,那么就会执行下面一段代码。如果这时候也没有设置一个名为-DDBUG_ON的CFLAGS的环境变量的话,就会增加一个CFLAGS:-DDBUG_OFF。 之后,当编译器编译的时候,根据编译器的参数增加的宏来决定 怎么定义 DBUG_ENTER 之类的函数是空代码,还是实际的报错代码。 [cpp] /* * These macros provide a user interface into functions in the * dbug runtime support library. They isolate users from changes * in the MACROS and/or runtime support. * * The symbols "__LINE__" and "__FILE__" are expanded by the * preprocessor to the current source file line number and file * name respectively. * * WARNING --- Because the DBUG_ENTER macro allocates space on * the user function's stack, it must precede any executable * statements in the user function. * */ # ifdef DBUG_OFF # define DBUG_ENTER(a1) # define DBUG_RETURN(a1) return(a1) # define DBUG_VOID_RETURN return # define DBUG_EXECUTE(keyword,a1) # define DBUG_PRINT(keyword,arglist) # define DBUG_2(keyword,format) /* Obsolete */ # define DBUG_3(keyword,format,a1) /* Obsolete */ # define DBUG_4(keyword,format,a1,a2) /* Obsolete */ # define DBUG_5(keyword,format,a1,a2,a3) /* Obsolete */ # define DBUG_PUSH(a1) # define DBUG_POP() # define DBUG_PROCESS(a1) # define DBUG_FILE (stderr) # define DBUG_SETJMP setjmp # define DBUG_LONGJMP longjmp # define DBUG_DUMP(keyword,a1) # else # define DBUG_ENTER(a) / auto char *_db_func_; auto char *_db_file_; auto int _db_level_; / auto char **_db_framep_; / _db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, / &_db_framep_) # define DBUG_LEAVE / (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)) # define DBUG_RETURN(a1) return (DBUG_LEAVE, (a1)) # define DBUG_VOID_RETURN {DBUG_LEAVE; return;} # define DBUG_EXECUTE(keyword,a1) / {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}} # define DBUG_PRINT(keyword,arglist) / {if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}} # define DBUG_2(keyword,format) / DBUG_PRINT(keyword,(format)) /* Obsolete */ # define DBUG_3(keyword,format,a1) / DBUG_PRINT(keyword,(format,a1)) /* Obsolete */ # define DBUG_4(keyword,format,a1,a2) / DBUG_PRINT(keyword,(format,a1,a2)) /* Obsolete */ # define DBUG_5(keyword,format,a1,a2,a3) / DBUG_PRINT(keyword,(format,a1,a2,a3)) /* Obsolete */ # define DBUG_PUSH(a1) _db_push_ (a1) # define DBUG_POP() _db_pop_ () # define DBUG_PROCESS(a1) (_db_process_ = a1) # define DBUG_FILE (_db_fp_) # define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1)) # define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2)) # define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2) # endif
推荐阅读
-
PHP利用MySQL保存session的实现思路及示例代码
-
举例介绍mysql数据库与oracle数据库的区别
-
nodejs简单访问及操作mysql数据库的方法示例
-
Mysql 8.0版本导出的sql文件在Mysql 5.5中运行出错
-
mysql中if函数的正确使用姿势
-
MySQL,必须掌握的6个知识点
-
Python导入txt数据到mysql的方法
-
常见的在Python中实现单例模式的三种方法
-
在 CentOS 7 中安装 MySQL 8 的教程详解
-
Linux连接mysql报错:Access denied for user ‘root’@‘localhost’(using password: YES)的解决