上一篇说了mysql的架构图,不少同窗反馈说不过瘾,毕竟仍是听我讲故事,那这篇就来讲一说怎么利用visual studio 对 mysql进行源码级调试,毕竟源码面前,不谈隐私,圣人面前,皆为蝼蚁。mysql
mysql是C++写的,要想在windows上编译,还须要下载几个必备小工具。sql
这里简单说一下:能够用 cmake 将源码生成 *.sln 可打开的解决方案,好比能够经过它最终生成 MySQL.sln。boost 是C++中很是强大的基础库,bison 一个流行的语法分析器程序,用于给mysql提供语法分析,最后就是下载正确的mysql版本5.7.12。windows
我会写的比较细,毕竟我也花了一下午时间,寒酸(┬_┬)bash
cmake 和 bison 安装起来比较方便,一键安装就能够了,不过这里有一个大坑注意了,在安装Bison的时候,千万不要使用默认路径,由于默认路径有空格,会致使你后面vs编译的时候卡住,又不显示什么缘由,可气!!! 因此我换成自定义的: C:\2\GnuWin32。架构
最后确保 cmake 和 bison 的bin文件都在 环境变量中便可。函数
这里我用 C:\2
做为根文件夹,全部的小工具都在这里,如图:工具
接下来将 mysql-5.7.12.zip
解压一下,而后进入解压后的文件夹,新建一个boost文件夹,将boost_1_59_0.tar.gz放入其中,而后再新建一个 brelease 文件夹可用于存放最终生成的MySql.sln
。😄😄😄。ui
都准备好了以后,能够开始cmake编译了。编码
PS C:\2\mysql-5.7.12\brelease> cmake .. -DDOWNLOAD_BOOST=1 -DWITH_BOOST="C:\2\mysql-5.7.12\boost\boost_1_59_0.tar.gz" -- Building for: Visual Studio 16 2019 CMake Deprecation Warning at CMakeLists.txt:26 (CMAKE_POLICY): The OLD behavior for policy CMP0018 will be removed from a future version of CMake. -- Cannot find wix 3, installer project will not be generated -- COMPILE_DEFINITIONS: _WIN32_WINNT=0x0601;WIN32_LEAN_AND_MEAN;NOGDI;NOMINMAX;HAVE_CONFIG_H -- CMAKE_C_FLAGS: /DWIN32 /D_WINDOWS /W3 /MP /wd4800 /wd4805 /wd4996 -- CMAKE_CXX_FLAGS: /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MP /wd4800 /wd4805 /wd4996 /we4099 -- CMAKE_C_FLAGS_DEBUG: /MTd /Z7 /Ob1 /Od /RTC1 /EHsc -DENABLED_DEBUG_SYNC -DSAFE_MUTEX -- CMAKE_CXX_FLAGS_DEBUG: /MTd /Z7 /Ob1 /Od /RTC1 /EHsc -DENABLED_DEBUG_SYNC -DSAFE_MUTEX -- CMAKE_C_FLAGS_RELWITHDEBINFO: /MT /Z7 /O2 /Ob1 /DNDEBUG /EHsc -DDBUG_OFF -- CMAKE_CXX_FLAGS_RELWITHDEBINFO: /MT /Z7 /O2 /Ob1 /DNDEBUG /EHsc -DDBUG_OFF -- Configuring done -- Generating done -- Build files have been written to: C:/2/mysql-5.7.12/brelease
当看到最后一句 Build files have been written to: C:/2/mysql-5.7.12/brelease
,恭喜你,MySQL.sln
生成好了。3d
个人电脑安装的是visual studio 2019
,接下来打开MySql.Sln总体编译,须要等个十几分钟,看到下面的输出就算安装成功。
这里要作两件事情,第一件事是将mysql的调试模式打开,第二件事就是附加 --initialize
启动参数。
修改C:\2\mysql-5.7.12\sql\mysqld.cc
中的 test_lc_time_sz
方法中的 DBUG_ASSERT(0); 改为 DBUG_ASSERT(1); 以下图:
上一篇你们都知道了,mysqld项目是mysql的启动项目,main函数也在其中,在F5调试以前增长初始化参数 --console --initialize
,以下图:
启动以后,有103个报错,气人呀。。。看错误信息应该是编码问题,以下图:
修改起来也很简单,将 C:\2\mysql-5.7.12\sqlsql_locale.cc
用 [utf-8 + BOM] 格式保存一下,而后对mysqld项目Rebuild再Ctrl+F5
直接运行,终于谢天谢地,从输出能够看到,搞定啦。。。太不容易啦。
从上图中能够看到,默认密码是:zJDE>IC5o+ya,先记录下这个密码,而后再把CommandLine Arguments 中的--initialize去掉再重启Console。
能够看到,3306端口已开启,而后用刚才的 zJDE>IC5o+ya 链接便可,这里我使用navicat。
链接上去后会提示修改默认密码,设置我就设置为:123456 ,😁😁嘿嘿,一切搞定~~~
上一篇咱们追踪到了 write_row 就断掉了,我当时说它是一个虚方法,由底层具体的存储引擎去调用,代码以下:
int handler::ha_write_row(uchar *buf) { MYSQL_TABLE_IO_WAIT(m_psi, PSI_TABLE_WRITE_ROW, MAX_KEY, 0,{ error= write_row(buf); }) } //这是一个虚方法 virtual int write_row(uchar *buf __attribute__((unused))) { return HA_ERR_WRONG_COMMAND; }
到底这话虚不虚,此次我亲自调试一下给你们看看,证据先行哈。。。为了方便,我生成一条创表sql。
drop database if exists `datamip`; create database `datamip`; drop table if exists `datamip`.`customer`; create table `datamip`.`customer` ( `customerID` int NOT NULL AUTO_INCREMENT COMMENT '自增主键', `customerName` varchar(50) COMMENT '用户姓名', `email` varchar(50) COMMENT '邮箱地址', `desc` varchar(50) COMMENT '描述', primary key (`customerID`) ) ENGINE=InnoDB charset=utf8 collate=utf8_bin;
接下来,你们看仔细了,在源码 int handler::ha_write_row(uchar *buf)
方法处下一个断点,而后F5调试应用程序。
接下来能够执行insert操做,这地方会命中断点的。
insert into `datamip`.`customer`(customerName,email,`desc`) values('mary','123456789@qq.com','vip');
能够看到,断点命中了,而后进行单步调试,最终你会看到代码会进入到 C:\2\mysql-5.7.12\storage\innobase\handler\ha_innodb.cc
中的 int ha_innobase::write_row
方法,以下图:
而后找几个局部变量和调用堆栈看看。。。
这就是我花了一下午的时间总结出的进坑出坑指南,但愿能帮助你们节省时间,仍是那句话,源码面前,不谈隐私,若还能进行调试,那一切皆为蝼蚁!