[MySQL Bug]使用DEBUG_SYNC调试多线程并发导致的bug

———————————————————-

这里以一个简单的bug(bug#58198)为例,本例使用的也比较简单,就用SIGNAL 和WAIT_FOR

我们对Percona Server 5.5.18注入如下代码:

在函数mysql_change_db_impl(use db时会调用)中:

Index: sql/sql_db.cc
===================================================================
--- sql/sql_db.cc       (revision 1185)
+++ sql/sql_db.cc       (working copy)
@@ -1291,7 +1291,7 @@
       the previous database name, we should do it explicitly.
     */
     my_free(thd->db);
-
+    DEBUG_SYNC(thd, "use_db_free");
     thd->reset_db(new_db_name->str, new_db_name->length);
   }

在函数mysqld_list_processes(show processlist时会调用)中:

Index: sql/sql_show.cc
===================================================================
--- sql/sql_show.cc     (revision 1185)
+++ sql/sql_show.cc     (working copy)
@@ -1880,8 +1880,10 @@
          thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
                                       tmp_sctx->host_or_ip :
                                       tmp_sctx->host ? tmp_sctx->host : "");
-        if ((thd_info->db=tmp->db))             // Safe test
+        if ((thd_info->db=tmp->db)) {            // Safe test
+          DEBUG_SYNC(thd, "after_read_db_ptr");
           thd_info->db=thd->strdup(thd_info->db);
+        }
         thd_info->command=(int) tmp->command;
         mysql_mutex_lock(&tmp->LOCK_thd_data);
         if ((mysys_var= tmp->mysys_var))

在show processlist时,在拷贝了tmp->db的指针后,有可能tmp->db所指向的内存已经被释放或被重用,这时候就在show processlist时就可能显示意料外的值,或者直接crash掉。。。。。

如下:

创建测试库

create database a;

create database abcde;

con1:

SET DEBUG_SYNC=’RESET';                 —RESET表示重置DEBUG_SYNC

use a;

con2:

SET DEBUG_SYNC=’RESET';

SET DEBUG_SYNC=”after_read_db_ptr SIGNAL have_show WAIT_FOR have_free”;

—–当执行到 DEBUG_SYNC(thd, “after_read_db_ptr”)时会发送一个信号名为”have_show”,然后再等待信号名为”have_free”

show processlist;

—–发送“have_show”,等待“have_free”

con1:

SET DEBUG_SYNC=”now wait_for have_show”;

—-等待接收到信号”have_show”

SET DEBUG_SYNC=”use_db_free SIGNAL have_free WAIT_FOR finish_show”;

—-当执行到DEBUG_SYNC(thd, “use_db_free”)时,发送”have_free”信号,等待finish_show信号

use abcde;

—-发送have_free,等待finish_show

con2 :

SET DEBUG_SYNC=”now SIGNAL finish_show”;

—-发送finish_show信号

时间: 2025-01-20 23:11:07

[MySQL Bug]使用DEBUG_SYNC调试多线程并发导致的bug的相关文章

《多核与GPU编程:工具、方法及实践》---- 3.9 调试多线程应用

3.9 调试多线程应用 调试多线程应用不仅仅是具备一个能够管理多线程的调试器.许多现代调试器支持线程的执行和独立调试,并支持指定线程的断点.观察窗等.本节不讨论调试器的具体实现方法.例如,图3-13展示了DDD--GNU DeBugger(GDB)前端,它执行代码清单3-24中公平的读者–写者解决方案.在UNIX/Linux中能够使用DDD和GDB(对于CLI困难)的唯一要求是在编译程序时添加调试支持选项,亦即使用编译器的-g开关. 多线程程序中的bug通常只有在与事件的某个精确时序有关的特定环

银行取款[多线程]{未进行线程同步}(junit不适合多线程并发单元测试)

        由于计算机多任务.多进程.多线程的支持,使得计算机资源的服务效率提高,服务器对请求的也使用线程来相应,所有,代码中涉及到同时对共享数据的操作,将在 多线程环境中操作数据,导致数据安全问题.      经典例子:老婆(朱丽叶)老公(罗密欧),使用银行卡和存折,或者网银等,同时对同一账户操作的安全问题.      如果要保证多线程下数据安全,就要实现线程同步(例如:一间小厕所,就得有一个锁,保证同一时间为一个人服务).其他文章讲: 此处用多线程实现,同时取款的模拟实现,未进行线程同步

浅谈java中异步多线程超时导致的服务异常_java

在项目中为了提高大并发量时的性能稳定性,经常会使用到线程池来做多线程异步操作,多线程有2种,一种是实现runnable接口,这种没有返回值,一种是实现Callable接口,这种有返回值. 当其中一个线程超时的时候,理论上应该不 影响其他线程的执行结果,但是在项目中出现的问题表明一个线程阻塞,其他线程返回的接口都为空.其实是个很简单的问题,但是由于第一次碰到,还是想了一些时间的.很简单,就是因为阻塞的那个线 程没有释放,并发量一大,线程池数量就满了,所以其他线程都处于等待状态. 附上一段自己写的调

利用C#线程窗口调试多线程程序

  从网上的资料判断,调试多线程程序似乎就一下3种方法. 1.在日志的某个地方写日志文件. 优点:不会干扰程序的执行,特别是对网络的多线程通信. 缺点:每次都需要打开日志文件以查看进程运行的信息. 2.利用断点进行调试. 优点:直观,可以直接看到运行过程的值 缺点:在多个线程设置断点,可能让程序跳来跳去,还需要额外地分出一部分精力用来理清程序的逻辑 3.利用弹出窗口来查看进程调试的信息. 优点;直观 缺点;在调试网路通信的时候,使得通信的过程产生延时,导致通信失败. 4.利用vs2010自带的线

解决Java多线程并发的计数器问题

问题描述 解决Java多线程并发的计数器问题 3C public class Counter { public static int count = 0; public synchronized static void inc() { count++; } public static void main(String[] args) { //同时启动1000个线程,去进行i++计算,看看实际结果 for (int i = 0; i < 1000; i++) { new Thread(new Ru

vs-visual studio调试多线程的问题

问题描述 visual studio调试多线程的问题 有一个前台页面定时刷新,调试的时候一定间隔发一个请求过来,导致调试的时候短点来回跳,怎么设定只调试第一个请求? 解决方案 你可以把定时器的请求先注释掉调试嘛,或者用TRACE的方式调试,打印信息到output窗口. 解决方案二: 收到数据后把定时器关掉,或者下断点加上条件判断 解决方案三: 应该可以尝试加入断点条件. 解决方案四: 调试多线程里的代码还是直接打log日志看比较好,尤其是这种时间间隔特别短的,有的时候设断点后,可能会影响程序整体

Cocos2d-x优化中多线程并发访问

多线程并发访问在Cocos2d-x引擎中用的不是很多这主要是因为中整个结构设计没有采用多线程.源自于Objective-C的Ref对象需要使用AutoreleasePool进行内存管理AutoreleasePool是非线程安全的所有不推荐在子多线程中调用Ref对象的retain(). release()和autorelease()等函数.另外OpenGL上下文对象也是不支持线程安全的.但是有的时候我们需要异步加载一些资源例如加载图片纹理.声音的预处理和网络请求数据等.如果是异步加载图片纹理我们可

C++ 6.0多线程并发,内存能上来,CPU不上来的问题

问题描述 C++ 6.0多线程并发,内存能上来,CPU不上来的问题 为什么C++ 6.0多线程并发CPU不上来?为什么C++ 6.0多线程并发CPU不上来? 解决方案 调试下看看工作线程是否在工作,还是根本没有执行. 解决方案二: 需要你的线程里是cpu密集型的代码才能占满CPU

MySQL数据库的安装调试和VC实现

(调试此Demo需要将目录里的mydb子目录拷到MySQL安装目录的data子目录下(我的是:D:\Program Files\MySQL\MySQL Server 5.0\data) 摘要:本文详细阐述了如何进行MySQL的安装.调试,以及如何用VC进行编译,实现数据的"添加.修改.删除"等功能. 一.MySQL的安装 可以考虑安装mysql-5.0.41-win32,当然你有更新的版本更好,注意选择"完全安装"(只有这样才会安装VC编译时需要的头文件等).安装后