在上一篇04优化钩子事件处理中,我们在钩子函数中引入了call和return事件的处理,对性能进行了优化. 细心的同学可能已经发现了,我们的hook函数中call事件和line都需要对整个断点表进行遍历,这其中其实是存在着一些冗余的.因为call事件只关心函数是否有断点,而line事件则只关心本函数内有哪些断点.所以我们可以想办法优化一下断点信息的数据结构,进一步提升性能. 源码已经上传Github,欢迎watch/star. 本博客已迁移至CatBro's Blog,那里是我自己搭建的个人博客…
我们之前已经支持了通过函数来添加断点,并且已经支持了行号的检查和自动修正.但是通过函数来添加断点有一些限制,如果在当前的位置无法访问目标函数,那我们就无法对其添加断点. 于是,本篇我们将扩展断点设置的接口,支持通过函数名称添加断点,以突破这个限制. 源码已经上传Github,欢迎watch/star. 本博客已迁移至CatBro's Blog,那是我自己搭建的个人博客,欢迎关注.本文链接 实现分析 由于Lua是动态类型语言,变量可以是任何值.而函数在Lua语言中又是第一类值,与其他值一样使用,可…
说到Lua代码调试,最常用的方法应该就是加一堆print进行打印.print大法虽好,但其缺点也是显而易见的.比如效率低下,需要修改原有函数内部代码,在每个需要的地方添加print语句,运行一次只能获取一次信息,下次换个地方又得重新添加print语句.而且有时候,事先并不知道该去哪打印.或者打印什么内容,需要通过运行中获取的信息才能确定. 当print大法无法满足我们的需求时,就需要类似断点调试这样更高级的调试功能.本文将从零开始编写一个Lua调试器,实现类似gdb的断点调试功能. 本文代码已开…
前面已经支持了几种不同的方式添加断点,但是必须事先在代码中添加断点,在使用上不是那么灵活方便.本文将支持动态增删断点,只需要开一开始引入调试库即可,后续可以在调试过程中动态的添加和删除断点.事不宜迟,我们直接进入正题. 源码已经上传Github,欢迎watch/star. 本博客已迁移至CatBro's Blog,那是我自己搭建的个人博客,欢迎关注.本文链接 实现分析 入口断点 尽管我们目标是支持动态添加断点,但还是需要一个入口,提供用户添加初始的断点.仍然像之前一样,在用户代码中显式添加的确可…
在前一篇01最小实现中,我们实现了Lua断点调试的的一个最小实现.我们编写了一个模块,提供了两个基本的接口:设置断点和删除断点. 虽然我们已经支持在断点进行变量的打印,但是需要自己指定层数以及变量索引,使用起来不是很方便.要进行upvalue打印的话,操作会更加麻烦.为了提升调试的方便性,我们决定封装一个通用的变量打印函数,可以通过变量名查找到对应变量的值进行打印.支持局部变量.upvalue以及全局的_ENV中的变量. 本文代码已开源至Github,欢迎watch/star. 本博客已迁移至C…
在前一篇中我们支持了通过函数名称来添加断点,我们同时也提到了在Lua中一个函数的名称的并不是确定的.准确的说,Lua中的函数并没有名称,所谓名称其实是保存这个函数值的变量的名称. 于是通过函数名称添加断点就造成了一定的不确定性,因为函数被调用时并不一定是以这个名字被调用的.另外,多个不同的函数也可能以相同的名字进行调用. 所以为了解决这个问题,本篇我们将继续扩展断点的设置接口,支持通过包名来添加断点.因为包名相对更具确定性,配合行号可以进行精确定位. 源码已经上传Github,欢迎watch/s…
在第一篇的01最小实现中,我们实现了一个断点调试的最小实现,在设置钩子函数时只加了line事件,显然这会对性能有很大的影响.而后来两篇02通用变量打印和03通用变量修改及调用栈回溯则是提供了一些辅助的调试接口,并没有对钩子函数进行修改. 我们本篇将在钩子中引入call和return事件的处理,尝试对性能进行优化. 源码已经上传Github,欢迎watch/star. 本博客已迁移至CatBro's Blog,那里是我自己搭建的个人博客,欢迎关注. 实现分析 当前的实现因为只加了line事件,执行…
前面两篇我们对性能做了一个优化,接下来继续来丰富调试器的特性. 我们前面提到过,函数内并不是所有行都是有效行,空行和注释行就不是有效行.我们之前在添加断点的时候,并没有对行号进行检查,任何行号都能成功添加断点.所以如果添加的断点行号是无效的,那么永远也不会断到那里.但是钩子里并不知道它是无效的,call事件仍然会以为函数有断点从而启动line事件,造成CPU的浪费. 所以本篇,我们将对断点的行号进行检查,对于不在函数范围内的行号直接添加断点失败:在函数范围内的行号则自动修正为下一个有效的行号:另…
在前面两篇01最小实现及02通用变量打印中,我们已经实现了设置断点.删除断点及通用变量打印接口. 本篇将继续新增两个辅助的调试接口:调用栈回溯打印接口.通用变量设置接口.前者打印调用栈的回溯信息,后者可以方便地修改变量的值,支持局部变量.upvalue以及全局的_ENV中的变量. 本文代码已开源至Github,欢迎watch/star. 本博客已迁移至CatBro's Blog,那里是我自己搭建的个人博客,欢迎关注. 调用栈打印函数 我们首先来实现调用栈回溯打印接口printtraceback(…
title author date CreateTime categories VisualStduio 打断点调试和不打断点调试有什么区别 lindexi 2018-08-10 19:16:52 +0800 2018-2-21 11:9:34 +0800 VisualStudio 调试 最近小伙伴告诉我,他的代码在打断点的时候,运行到断点,之后就可以运行.如果没有断点,他的代码就无法运行,经过了一段时间的研究才发现,原来打断点和不打断点是有一些区别. 本文来告诉大家,如果在自己的软件发现打断点…
有时候我们必须启动debug模式来进行调试,在IDEA中断点调试与Eclipse大致相同: 1.以debug模式启动服务器: 2.在需要打断点的那一行前面点击一下标记上红点则是有断点,再次点击可以清除断点: 访问:http://localhost/SSM/user_find进入断点调试: (1) 断点调试类似于Eclipse: F5 进入方法 F6 进入下一步 F8 跳过此断点到达下一断点 (2)如果想在不删除断点的情况下跳过断点,可以点击下面的按钮(Mute Breakpoints): 其功能…
项目使用ulua,我神烦这个东西.lua单纯在lua环境使用还好,一旦要跟外界交互,各种月经不调就来了.要记住贼多的细节,你才能稍微处理好.一个破栈,pop来push去,位置一会在-1,一会在-3,21世纪已经过去五分之一了好吗,谁乐意像汇编一样操作?那十几个操作函数,愣是比正则表达式规则还难记,用完就忘.我发现lua心智负担完全跟简洁搭不上边,贼他娘重,实现个面向对象都乱七八糟.我学c++都没觉得有什么不爽的,就lua代码各种不乐意看,各种小tips在那里,什么meta,weak,_G,逼着你…
这是道哥的第008篇原创 一.前言 上篇文章我们聊了gdb的底层调试机制,明白了gdb是利用操作系统提供的系统信号来调试目标程序的.很多朋友私下留言了,看到能帮助到大家,我心里还是很开心的,其实这也是我继续输出文章的最大动力!后面我会继续把自己在项目开发中的实战经验进行总结. 由于gdb的代码相对复杂,没有办法从代码层面仔细的分析调试细节,所以这次我们选择一个小巧.开源的Lua脚本语言,深入到最底层的代码中去探究一下代码调试真正是怎么一回事. 不过请放心,虽然深入到代码最底层,但是理解难度并不大…
上面的例中,当打断点调试时,断点断住时, Attr1属性的get块就会执行一次. 两个断点加在逻辑中对Attr1的访问,最后发现CTest get Attr1.打印了3次. 得到的结论是:多余的2次打印是由于断点使得程序中断引发的,中断后调试器需要获取Attr1的数值,对get块进行调用. 不调试直接运行程序,发现只打印1次CTest get Attr1.  与预期相符! 这是调试器引发的海森伯效应.调试状态下,Attr1的get逻辑被执行n次. 所幸,vs提供了调试选项来关闭调试器的这种行为:…
断点调试的方法: 断点调试在程序比较大的时候调试运用的比较多 点击Pycharm软件右上角绿色三角形右边的小甲鱼图标,点击之后会弹出断点调试的界面 Debug是用来调试bug的 terminal 是终端 查看结果的 ,运行程序那里有一个总的终端,在debug这里,也有一个终端 debug之后 左边有个绿色的图标 一个竖线,加一个三角形 这个是运行程序 从一个断点 运行到下一个断点 断点就是点击程序所在行左侧的空白处,会出现一个红色的圆点,这个就是断点的标志 右上角 绿色小甲鱼 debug断点调试…
环境是:wamp PHP Version: 5.5.12 网上的教程很多,我自己按照教程操作,实现了断点调试,下面是我设置断点调试的步骤 1.修改配置文件php.ini,按下面修改(位置在最后) ; XDEBUG Extension zend_extension = "D:/wamp/bin/php/php5.5.12/zend_ext/php_xdebug-2.2.5-5.5-vc11.dll";[xdebug]xdebug.remote_enable = onxdebug.remo…
问题描述 今天突然碰到了这样的一个问题: 使用断点调试时,断点的地方出现了一个叉号,而不是对勾,这就让我非常无奈了. 调了一天,终于把这个问题解决了,还是要记录一下的. 问题情况如下: 除了这里,debug标志位也弹出了问题. 问题出现的原因 这个问题之所以会出现,主要是因为svn本身的问题,或者是编译的时候出现了未知错误导致部分内容没有编译. 解决方法 这里给出几种方法: 清除缓存 File ---> invalidate Caches / Restart 一般使用这个方法都是奏效的,如果没有…
最近调试一个离职的同事留下的工程,DEBUG模式下顺利,RELEASE的时候就崩溃了,显示为"帧不在模块中"--简直一头雾水 于是我修改配置,为了能够在Release模式中打断点调试和输出错误信息. 1 在资源视图中,打开工程的属性窗口 2 C++  常规 调试信息格式: 选择  程序数据库(/Zi)或(/ZI):注意:如果是库的话,只能(Zi) 3 C++ 优化 配置窗口中 禁用优化/0d 4 链接器 调试 配置窗口中 将生成调试信息修改为 是/DEBUG 调试完成后准备打包前再调整…
Android Studio断点调试 Android Studio包含一个debugger程序,可以帮助你在模拟器和真机上调试你的android应用.通过Android Studio的debugger,你可以: 选择你想调试的设备. 在代码上设置断点. 在运行时去检查变量和表达式的值. 可能平时大家调试代码都是通过打印log的形式,今天带大家走进断点调试的世界. 断点调试-基础篇 设置断点 设置断点的方法: 左键在需要调试的代码所处的侧边栏处单击.如下图所示:  开始调试 点击红色箭头指向的按钮…
Lua+Redis 断点调试环境搭建 windows环境,使用Redis,写lua脚本头疼的问题之一不能对脚本断点调试,google加上自己的摸索,终于搞定. 1.下载ZeroBraneStudio,我下载的是破解版(我自己为自己感到可耻,其实并不贵,百十来块钱的样子) 解压后在bin下有lua解释器的路径,把该路径添加到环境变量中:假设解释器路径是:D:/ZeroBraneStudio/bin/lua.exe,那么就把D:/ZeroBraneStudio/bin添加到Path环境变量下. 2.…
到目前为止我们的调试手段只有一种: 根据程序执行时的出错现象假设错误原因,然后在代码中适当的位置插入printf,执行程序并分析打印结果,如果结果和预期的一样,就基本上证明了自己假设的错误原因,就可以动手修正Bug了. 如果结果和预期的不一样,就根据结果做进一步的假设和分析. 这里,我们介绍一种很强大的调试工具gdb,可以完全操控程序的运行,使得程序就像你手里的玩具一样,叫它走就走,叫它停就停,并且随时可以查看程序中所有的内部状态,比如各变量的值.传给函数的参数.当前执行的代码行等. 有了gdb…
之前说过断点调试,但是针对的是单文件的断点调试.在实际应用中,一个项目是多目录多文件的 参考资料:gdb debugger 目录结构: $ tree .├── gdbSomeFiles.cpp├── Libs│   ├── add.cpp│   ├── add.h│   └── makefile└── makefile add.h #pragma once class CAdd { public: CAdd(void); int add(int &a, int &b); virtual ~…
ok,前面准备给一个dll写wrapper,写了篇日志,看似写的比较明白了,但是其实有很多米有弄明白的.比如PIL中使用的element,key,tname,field这些,还是比较容易混淆的.今天正好搞搞清楚. 1.stack 这个应该不用多讲了,C和lua中的交互就是基于一个stack的,而且每次lua调用一个c函数,都是给分配一个新的stack.它的原型: typedef int (*lua_CFunction) (lua_State *L); stack中的基本单元在PIL中多成为ele…
lua中的协程和线程类似: 1. 协程拥有自己的独立的栈,局部变量,和指令: 2. 所有协程都可以共享全局变量: 3. 协程不能像线程那样并行执行,协程之间需要相互协调执行,同一个时刻只能运行一个协程: 如何使用协程: coroutine.create:创建一个协程,返回一个协程句柄: coroutine.status:查看一个协程的状态,suspended,running,dead,normal: coroutine.resume:恢复一个协程的执行,如果正常就返回true,错误返回false…
如果你看了LUA的文档,那么就应该很清楚LUA与C交互数据时都是用到LUA中所谓的stack.那么当我调用lua_open函数之后栈是什么样的呢?空的(luaopen_base等会往栈上加进一些东西).那么至于如何操作栈上的数据,我想官方文档上已经说得很清楚了,不过最初我对于栈的顺序有一些迷糊,所以就说说这个.现在假如我有如下的一段代码: 代码: lua_State* L = lua_open();lua_pushnumber( L, 211 );lua_pushnumber( L, 2222…
lua中的require机制    为了方便代码管理,通常会把lua代码分成不同的模块,然后在通过require函数把它们加载进来.现在看看lua的require的处理流程.1.require机制相关的数据和函数    package.path:保存加载外部模块(lua中"模块"和"文件"这两个概念的分界比较含糊,因为这个值在不同的时刻会扮演不同的角色)的搜索 路径,这种路径是"模板式的路径",它里面会包含可替代符号"?",这…
Lua中的捕获   捕获 捕获是这样一种机制:可以使用模式串的一部分匹配目标串的一部分.将你想捕获的模式用圆括号括起来,就指定了一个捕获.在string.find使用捕获的时候,函数会返回捕获的值作为额外的结果.这常被用来将一个目标串拆分成多个: pair = "name = Anna"_, _, key, value = string.find(pair, "(%a+)%s*=%s*(%a+)")print(key, value)    --> name …
原文:(PDF) . 摘要 一等(first-class)函数是一种非常强大的语言结构,并且是函数式语言的基础特性.少数过程式语言由于其基于栈的实现,也支持一等函数.本文讨论了Lua 5.x用于实现一等函数的新算法.与之前所使用的技术不同,该算法不需要对源代码做静态分析(一种会极大降低Lua代码生成器即时性的技术)并且可支持使用顺序栈存储常规局部变量. 1 介绍 一等函数是函数式语言的标志性特征,在过程式语言中也是很实用的概念.很多过程式函数如果以高阶函数的形式编写则会增加可读性.例如,C语言标…
[转载自]http://blog.chinaunix.net/uid-552961-id-2736410.html lua中的require机制 为了方便代码管理,通常会把lua代码分成不同的模块,然后在通过require函数把它们加载进来.现在看看lua的require的处理流程. 1.require机制相关的数据和函数    package.path:保存加载外部模块(lua中"模块"和"文件"这两个概念的分界比较含糊,因为这个值在不同的时刻会扮演不同的角色)的…
一篇不错的帖子,讲的是gdb中的信号(signal)相关调试技巧 转自Magic C++论坛  http://www.magicunix.com/index_ch.html  http://www.magicunix.com/cgi-bin1/forum_cn/ultimatebb.cgi?ubb=get_topic&f=1&t=000060#000003 引用:  --------------------------------------------------------------…