关于调试:开源调试软件OpenOCD调试stm32

刚开始接触嵌入式硬件时只晓得写程序,感觉调试基本不须要,随着工夫的积攒和问题复杂度的晋升,才发现调试对于一个零碎的重要性。生存中很多这样的例子,调试,永远都是事物良性倒退过程中必不可少的一个环节,两个人过日子遇到了矛盾,静下来沟通就是调试,总不能一言不合就离别。在设计一个产品或者一个流程时,都要充沛的思考到调试因素,这样零碎在运行过程中一旦呈现了问题,能够及时的追溯。 OpenOCD就是这样一个工具,配合JTAG调试协定,能够对硬件设施进行指令集级别和寄存器级别的调试。 理解一个新软件最好的形式就是读官网的Manual。当然,不肯定非得从Manual开始,能够从一些实例开始,或者基于母语的博客或者论坛,但想把握得更彻底,还是得找官网的文档,解铃还须系铃人。如果软件的设计思维过于简单,Manual读一遍是不论用的。往往回旋式的后退会收到更好的成果,也就是带着问题读Manual,解决了问题;再遇到一些问题时,再读一遍Manual,就这样重复几遍也就逐步把握了,所谓的一万小时实践也是基于此。 OpenOCD的劣势就是开源,反对N种调试器。充沛的了解和把握整个开发过程中的调试办法,是我的项目稳固进行的牢靠保障,很多未知问题都得通过底层调试能力剖析进去。 调试ARMwindows应用gdb调试stm32能够应用几套环境: stlink硬件+openocd软件+arm-none-eabi-gdbjlink硬件+openocd软件+arm-none-eabi-gdbjlink硬件+jlink_gdb_server软件+arm-none-eabi-gdb搭建环境这里先讲第二种状况的应用: 通过网站http://www.freddiechopin.info/en/download/category/4-openocd下载openOCD for windows软件包,当初的版本是0.9.0。如果心愿下载源代码,能够拜访网站http://openocd.sourceforge.net/。登陆网站http://zadig.akeo.ie/下载zadig软件,用来装置仿真器的驱动程序,以后版本是2.1.2,说的直白一些openOCD只把Jlink仿真器当作一般的USB设施来应用,不应用Jlink自带的仿真器驱动程序,如果已装置了Jlink仿真器驱动程序,这个过程就是把原先的驱动程序换掉。插入Jlink仿真器(如果是第一次插入Jlink仿真器,零碎会要求装置驱动程序,咱们能够点击勾销,不用理睬),运行zadig软件。抉择J-Link,而后抉择WinUSB驱动程序,点击Reinstall Driver按钮或Replace Driver按钮,这样便实现了驱动程序的替换。解压缩openOCD软件包,在硬盘上建设openocd文件夹(可写其它的任意名称),拷贝bin和scripts文件夹上面的所有文件到该文件夹。应用Jlink仿真器连贯指标板,并给指标板上电。在windows运行中输出cmd,启动控制台程序,并切换至步骤7建设的文件夹。输出命令openocd -f interface/jlink.cfg -f target/k60.cfg,jlink.cfg示意应用jlink仿真器,k60.cfg示意下载k60系列MCU。呈现下列界面示意连贯胜利。 openOCD思考OpenOCD是一款功能强大的开源调试软件,反对多种调试器,例如Jlink、STlink、FT2232、并口等;反对多种嵌入式处理器,例如ARM7,ARM9, ARM10, ARM11和Cortex等外围的芯片;另外还提供一个GDB Server接口。 刚一开始可能还摸不清OpenOCD的运作模式,毕竟它不是一款图形化软件,而是基于command line 的交互方式。而且OpenOCD运行后间接就是一个Daemon,我第一次运行时还真有点懵。这种软件还是得靠入手操作实例来把握。 应用OpenOCD开发我的项目,咱们须要做的不止是将调试器连贯到开发板,咱们还须要配置OpenOCD让它晓得咱们的调试器和开发板的型号,能够应用OpenOCD连贯GDB,而后应用例如Eclipse或者其它图形化的工具。 下一篇文章,咱们会写连贯到开发板后,如何进行调试。并且通过OneOS-Lite进行教学实战。 TAPTest Access Ports (TAPs) are the core of JTAG. TAPs serve many roles, including: 测试拜访端口TAPs是JTAG的外围,TAPs服务许多角色,包含: Debug TargetA CPU TAP can be used as a GDB debug target.调试指标端CPU TAP能够作为GDB调试的指标端程序,即GDBServer。艰深点讲,TAP就是一个调试链,通常一个芯片就是一个TAP,然而一个芯片往往蕴含多个IP核,比方,ARM+DSP或者ARM+FPGA或者ARM+ASIC,所以在这个chain外面通常会蕴含多个可调试对象,比方应用scan_chain命令显示的信息,能够看到omap5912上面包含3个可调试成员。 OpenOCD启动时将配置文件作为参数. openocd.exe -f jlink.cfg -f openocd-ralink.cfg 命令就是将jlink.cfg和openocd-ralink.cfg两个配置文件作为配置参数。 怎么学openOCD其实也很简略。首先晓得openOCD是搞毛线用的。 而后,晓得怎么搭建环境。比方须要什么硬件J-Link/st-link,什么软件openOCD,zadig等。 环境搭建好当前,晓得如何输出命令来和指标机连贯。 晓得openOCD的常用命令,晓得如何剖析和更改配置文件。 晓得如何配合gdb进行调试。 如果以上都搞定,那么我就认为,openOCD曾经能够失常相熟应用了,剩下的就是一直尝试和欠缺本人的openOCD的常识体系结构了。 比照JLink驱动通过下面的学习,咱们能够看到openOCD只把Jlink仿真器当作一般的USB设施来应用,不应用Jlink自带的仿真器驱动程序。也即是说:openOCD代替了jlink驱动提供的性能。 关注&&分割gitee: https://gitee.com/cmcc-oneos/OneOS-Lite docs: https://oneos-lite.com/ ...

November 19, 2021 · 1 min · jiezi

关于调试:多媒体开发8调试FFmpeg

编译FFmpeg失去二进制文件,之后就是对二进制库的调用,这时FFmpeg就像一个黑盒子。作为程序员,难道不想钻研一下FFmpeg的具体实现?比方是怎么拿到歌曲信息的、怎么解码的、怎么推流的,等等。 看源码是了解代码实现的一个方法,而单步调试能从另一个维度去帮到你。本文介绍如何单步调试FFmpeg的代码。 (一)为什么要调试调试的益处,一来能够了解程序的执行流程,二来有助于定位问题。 绝对于看源码,单步调试,能够看到数据的变动,会粗浅很多,而且定位问题时也直观疾速,你甚至能够批改变量的值或下条件断点,充分发挥调试器的性能。 所以调试是了解代码与定位问题的无效方法。 (二)怎么调试小程用的是mac机。先实现FFmpeg源码下载与编译的筹备工作。 (0)下载FFmpeg源码git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg或者: curl -0 http://ffmpeg.org/releases/ffmpeg-\${VERSION}.tar.bz2tar jxvf ffmpeg-\${VERSION}.tar.bz2VERSION设置为最新的ffmpeg版本号。 至于用什么工具来关上这些源码文件,你应该思考适宜本人,而且适宜看大型项目的工具,比方sourceinsight、sublime、vim、emacs、xcode、Android Studio之类。 (1)编译FFmpeg编译要应用到编译器,在mac机上最简略的方法就是装置xcode了,这样保障编译器clang是存在的。 为了调试,这次的编译能够很简略,只有把优化选项去掉,再make即可: make clean./configure --disable-optimizationsmake configure是FFmpeg提供的配置脚本,用来生成Makefile跟config.h文件,Makefile在编译时应用,而config.h(外面各种宏的定义)被FFmpeg源码应用,也会影响到FFmpeg的性能裁剪。 对于configure的参数,你也能够通过./configure --help来查看所有的选项,而后再找到对于优化的选项。 这里的make clean,是为了清一下之前的编译净化,如果之前没有编译过,那就不须要执行。 另外,如果make之后,再执行make install,就会把FFmpeg装置到mac零碎。对于调试来说这个是不必要的,只有make出二进制库就好了。 胜利编译后,能够看这几个文件: (2)用gdb调试FFmpeg如果你喜爱用命令行,那应用gdb或lldb来进行调试是不错的抉择。 在应用gdb前,须要装置并给gdb签名,如果你还没有筹备好gdb,并且有趣味应用gdb的话,能够浏览分割线以内的内容,这外面也包含了gdb罕用的命令。 装置gdb: brew install homebrew/dupes/gdb对gdb受权,参照: https://blog.csdn.net/cairo12... 写一个测试的例子: touch gdbtest.c:int main() { int a = 10; printf("%d\n");}编译: gcc -o gdbtest gdbtest.c -g留神须带-g,以生成符号dSYM文件。 而后就能够调试了,常用命令有这些: gdb gdbtest --加载可执行程序r --run,运行,能够带参数i b --info break,断点信息b 3 --break 3,第3行下断点b main --main函数第一行下断点b other_c:fun1 --文件other_c的fun1函数第一行下断点b 120 --在120行下断点clear --删除所有断点d 3 --delete 3,删除断点3disable 1 --禁用断点1enable 1 --启用断点1s --step,跳进去f --finish,跳进去n --next,执行一行n 3 --next 3,执行3行c --continue,持续直至下一个断点或完结p a --print a,输入变量a的值list/l --查看代码q/kill --退出本次调试bt --查看调用堆栈return --把以后函数return为了便当,我间接用FFmpeg的程序来切入调试(当然也能够写本人的代码来调用FFmpeg),比方能够抉择ffplay_g这个程序来切入,调试它所依赖的根底即FFmpeg。 ...

February 25, 2021 · 1 min · jiezi

关于调试:手机hybrid应用H5开发

H5开发引入flexible.js在*.html的<head>标签中引入<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>Note:HTML中无需设置<meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no,minimum-scale=1.0,maximum-scale=1.0">,否则,不论设施是多少的dpr,都会强制认为其dpr是你设置的值。 通过scss定义px2rem的转换@function px2em($px, $base-font-size: 16px) { @if (unitless($px)) { @warn "Assuming #{$px} to be in pixels, attempting to convert it into pixels for you"; @return px2em($px + 0px); // That may fail. } @else if (unit($px) == em) { @return $px; } @return ($px / $base-font-size) * 1em;}文本字号不倡议应用rem咱们心愿文本在不同dpr屏幕下文本字号雷同咱们心愿在大屏手机上看到更多文本 不心愿呈现13px和15px这样的奇葩尺寸 文本还是应用px作为单位,只不过应用[data-dpr]属性来辨别不同dpr下的文本字号大小 // dpr === 1, 设计图尺寸375 * 667为例@mixin font-dpr($font-size){ font-size: $font-size; [data-dpr="2"] & { font-size: $font-size * 2; } [data-dpr="3"] & { font-size: $font-size * 3; }}// dpr === 2, 设计图尺寸750 * 1135为例@mixin font-dpr($font-size){ font-size: $font-size / 2; [data-dpr="2"] & { font-size: $font-size; } [data-dpr="3"] & { font-size: $font-size; }}@include font-dpr(16px);H5调试手机开启USB调试性能不同手机开启门路不同,能够自行百度; ...

February 21, 2021 · 1 min · jiezi

关于调试:再见本地环境腾讯云全球首发Serverless-在线远程调试

在线调试是云函数为了解决用户在本地搭建调试环境简单,云上环境不便于定位等问题推出的性能。 云上的各种服务,在本地无奈齐全模仿,程序员大都遇到过本地和近程环境运行后果不统一的情景,追究起来费时费力,不仅效率低下,也造成十分郁闷的工作体验。 所以,是否间接在近程环境中实现全副的开发流程,是晋升开发体验的最间接伎俩,然而在其余问题都解决后,近程调试性能是最初的一公里。 本篇文章将以一段内存透露的代码为例,给大家展现如何应用云函数在线调试功能定位和解决问题。Node10 及以上版本的 runtime,应用 Chrome 浏览器关上云函数控制台,在函数代码页即可看到在线调试的入口。 开启调试模式应用Chrome浏览器关上函数代码编辑页,能够看到在【近程调试】页。为保障调试的体验,开启调试模式将批改函数的局部配置,包含函数进入单实例模式、函数超时工夫批改为900秒等。开启前请务必确认这些调整。 待加载实现后,页面将主动展现入口文件。 找不到须要的文件?应用快捷键 Cmd + P(Mac)或 Ctrl + P(Windows)能够关上所须要的文件。但大家可能会发现,刚开启调试模式时,关上文件的列表中找不到所须要的文件。这是因为对于动静脚本语言来说,调试器不会加载所有的内容,只会加载执行过的文件。咱们先点击测试,让函数运行一次。在运行一次后,咱们就能够关上所须要的文件了。 设置断点在代码前点击即可设置断点,在右上角的工具中能够进行继续执行、跨步执行、单步执行等操作,也能够灵便地启动或禁用断点。 内存透露排查 - 内存快照这部分介绍如何应用内存快照性能排查内存透露的问题。内存透露的排查办法大抵为:找准内存透露的机会,在透露的前后对内存进行快照,通过比照快照的内容判断内存透露的问题点。 首先,咱们将调试的窗口切换到 Memory 页面,点击左上方的实心圆形按钮捕获内存快照。 这样,咱们就有了运行前的内存快照。当初咱们执行存在内存透露的代码。这行代码有一个从未清理的全局缓存,随着调用的减少,越来越占内存。 随后,咱们进行第二次内存快照,关上比照页面,通过对Delta值的剖析,能够发现 concatenated string 这个局部减少了很多,很有可能有问题。 关上当前,便能够发现内存中多存储了很多“recording time”的数据。 这些重复性的数据也就意味着代码中呈现了内存透露,在代码中找到相干内容,进行调整,解决内存透露的问题。 除了云函数的控制台,也能够应用 Serverless Framework Dev 模式开启在线调试的性能。

January 27, 2021 · 1 min · jiezi

前端面试每日-31-第203天

今天的知识点 (2019.11.05) —— 第203天 (我也要出题)[html] canvas的width与height属性的值可不可以带单位?[css] height和line-height的区别是什么呢?[js] 你平时是怎么调试js的?会断点调试吗?断点调试有什么技巧呢?[软技能] 前端如何防止XSS攻击?《论语》,曾子曰:“吾日三省吾身”(我每天多次反省自己)。 前端面试每日3+1题,以面试题来驱动学习,每天进步一点! 让努力成为一种习惯,让奋斗成为一种享受!相信 坚持 的力量!!!欢迎在 Issues 和朋友们一同讨论学习! 项目地址:前端面试每日3+1 【推荐】欢迎跟 jsliang 一起折腾前端,系统整理前端知识,目前正在折腾 LeetCode,打算打通算法与数据结构的任督二脉。GitHub 地址 微信公众号欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个Star, 同时欢迎微信扫码关注 前端剑解 公众号,并加入 “前端学习每日3+1” 微信群相互交流(点击公众号的菜单:进群交流)。 学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布面试题(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!(不忘初心,html、css、javascript才是基石!)欢迎大家到Issues交流,鼓励PR,感谢Star,大家有啥好的建议可以加我微信一起交流讨论!希望大家每日去学习与思考,这才达到来这里的目的!!!(不要为了谁而来,要为自己而来!)交流讨论欢迎大家前来讨论,如果觉得对你的学习有一定的帮助,欢迎点个[Star] https://github.com/haizlin/fe...

November 5, 2019 · 1 min · jiezi

vscode-调试-帮助你快递开发

前端不只是只能在浏览器调试,现在越来越多单页面,在编辑器里面进行调试将大大提高你的开发效率~~ 1、调试vue 开发环境需要打开 source-map 方便调试 workspaceRoot 为根路径 在 launch.json 中配置 { "version": "0.2.0", "configurations": [ { "type": "chrome", "request": "launch", "name": "vuejs: chrome", "url": "http://localhost:8087", // 8087 为你启动vue项目的端口 "webRoot": "${workspaceFolder}/src", "breakOnLoad": true, "sourceMapPathOverrides": { "webpack:///src/*": "${webRoot}/*", "webpack:///./src/*": "${webRoot}/*" } }, ]}然后按 F5 就会启动一个google 的页面在编辑器里就可以打断点了 2、调试 node 环境下某个 js 文件 { "version": "0.2.0", "configurations": [ // 此为数组可以写多个 { "type": "node", "request": "launch", "name": "Launch Program", "program": "${workspaceRoot}/build/creat.js" }, ]}3、调试 node 后台项目 注意:自己写node时候一般是 node ./bin/www 启动一个服务,调试时候不需要启动直接 按 F5 启动调试即可(会自动启动服务) 否则会导致端口冲突调试失败 ...

August 8, 2019 · 1 min · jiezi

Xdebug-远程调试你会用吗

前言在开发过程中,我们最少不了的就是调试,因为 php 不能像 Java 和 C# 那样与生俱来的优势,拥有开箱即用的断点调试,很多时候我们的开发者都是使用的 var_dump 方法来对结果进行输出,而有的时候需要查看调用栈时,有的开发者甚至都不知道如和下手。(可以 throw 异常 或者 使用 debug_print_backtrace 和 debug_backtrace 来打印调用栈),虽然很多开发者知道xdebug 但是也会因为其繁琐的安装望而却步,又或许你在本地高高兴兴搭建好了,有时候要调试一下外网的,比如测试服务器,你会发现这是个坑,很多文章都没有正确的引导你去如何的安装它。 服务器如何安装 Xdebug环境准备ubuntu 16.04php 7+XShell首先打开 Xdebug 官网。 是不是看到硕大的 Download 链接吸引到了你,如果你知道你的 php 是什么版本 你可以在这里愉快的下载,然后并安装。 偶,我凑,怎么全是 Windows 的,Linux 的呢?Linux 当然是要从源码构建啦。 我凑,不会?没关系咱们一起来学一学,首先新建一个 php 文件,如果你是用包管理器安装的那么请直接跳转到包管理器 // info.php<?phpphpinfo();然后放到你的 web 目录,看清楚,一定是 web 目录。不要觉得你耍小聪明,使用 php -S 来启动一个临时的 web 服务器,不允许,因为你这样用到的 php.ini 是 cli 的,而不是 fpm 的,当 phpinfo 信息显示出来。 然后我们回到官网,点击下载页面的 custom installation instructions. ...

July 16, 2019 · 3 min · jiezi

移动端H5调试技巧

chrome://inspect/#devices

July 10, 2019 · 1 min · jiezi

移动端真机调试实战经验安卓篇

android手机+pc,pc可以是windows也可以是mac安卓手机只需要下载chrom浏览器,就可以再电脑上用chrom调试了,是不是很赞(づ ̄3 ̄)づ╭ 首先需要装chrom浏览器 打开手机的开发者模式,一般是:设置->关于手机->版本号连按5次,之后设置菜单中会多出一个开发人员选项,进入将其中的“usb调试”打开 将手机与电脑通过usb连接,弹出对话框“是否允许usb调试”,选择确定 在手机chrom上打开要调试的页面 在电脑上打开chrom,新开一地址栏为chrome://inspect/的页面,然后就可以调试了 点击inspect弹出chrom调试工具

July 9, 2019 · 1 min · jiezi

内网穿透神器FRP

frpfrp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp, http, https 协议原文地址 目前主要的场景是内网穿透,可以用于本地调试微信接口、本地站点公网访问等。 本文主要讲解: frp客户端配置frp服务端配置&&搭建准备frp执行区分不同的平台,在服务器上执行命令: arch如果输出x86_64则需要下载带linux_amd64的那个压缩包;如果输出的是其他的,则在文件列表中找 linux 的对应架构的压缩包 frp_0.20.0_darwin_amd64.tar.gz macfrp_0.20.0_linux_arm64.tar.gz linuxfrp_0.20.0_windows_386.zip windows然后尝试运行./frps --help, 正常会输出帮助信息。 如果提示-bash: ./frps: cannot execute binary file: Exec format error就说明你下错版本了。 客户端-frpc客户端和服务端版本号一致,目前使用的是v0.20.0。 启动命令: ./frpc -c frpc.inifrpc.ini客户端配置(必须) [common]# frp 服务器端地址,ip或域名server_addr = frp.xxx.com# frp 服务端端口,即填写服务端配置中的 bind_portserver_port = 7000token = xxxxxHTTP(S)[apixxx]# http 或 httpstype = http# 默认不需要改变ip,指向本地local_ip = 127.0.0.1# 对应服务的端口号local_port = 9000# http 可以考虑加密和压缩一下use_encryption = trueuse_compression = true# 自定义访问网站的用户名和密码,如果不定义的话谁都可以访问,会不安全http_user = adminhttp_pwd = admin# 对应远程的访问地址web0.frp.xxx.com:10080# frp.idayer.com 为服务端配置的 subdomain_host subdomain = web0TCP/UDP 范围转发# 自定义一个配置名称,格式为“[range:名称]”,放在开头[range:multi-port]type = tcplocal_ip = 127.0.0.1use_encryption = falseuse_compression = false# 本地端口和远程端口可以指定多个范围,如下格式,且范围之间必须一一对应local_port = 6010-6020,6022,6024-6028remote_port = 16010-16020,16022,16024-16028最后我们的配置结果如下: ...

July 8, 2019 · 2 min · jiezi

如何提高后台服务应用问题的排查效率日志-VS-远程调试

转眼间,距离Jerry最近一篇文章推送已经过去了一个多月的时间了。 公众号更新的频率降低,不是因为Jerry偷懒,而是由于从春节过后,我所在的SAP成都研究院数字创新空间整个团队,一直在忙一个5月份需要交付的项目上。 Jerry每天的工作量像下面这张图这样: 这个项目里Jerry负责的是后台开发工作,我用nodejs开发了若干微服务,每个微服务实现一个特定的业务逻辑。这些微服务由Jerry另外开发的一个编排器(Orchestra)统一调度。整套后台实现部署在亚马逊云平台(Amazon Web Service,以下简称AWS)上。 离交付日期越来越近了,我们的功能也赶得差不多了。本地测试运行得很好的场景,部署到AWS上运行后出现了一些bug。比如昨天就遇到一个棘手的bug,因此有了今天这篇文章。 2014年五一节的前一天,当时Jerry还在SAP CRM开发团队工作,负责处理SAP CRM中间件的一个bug。这个bug和代码执行时序有关,每执行一次只有40%的几率能重现,花了我整整一天(8个小时)的时间调试。因为重现bug的场景太复杂,需要调试的ABAP代码量太大,所以让我印象深刻。那个bug处理完之后,我也对自己花了8小时才搞定该bug的效率很不满意,因此写了一篇博客总结这次排错的经验教训: My Tips about how to handle complex and tricky issues https://blogs.sap.com/2014/05... 回到昨天我遇到的在AWS上出现的bug,根据问题的表象,一开始我和负责前端开发的同事,连这个问题出在前端还是后端都没办法判断。当微服务部署在本地并进行测试时一切正常,只有部署在AWS上进行集成测试时才会暴露,而运行在AWS上的nodejs应用,我昨天还不知道如何调试,因此只好采用我大二刚学C语言编程时用过的最笨的排查办法:打日志。 2001年,在结束了一年的计算机专业基础课学习后,Jerry开始了Unix环境下C语言编程的学习。当时我对gdb这种以命令提示行方式进行的调试风格很不适应,大多数时候的排错采用的还是在代码里添加printf语句打印变量内容的方式来进行,被寝室的同学鄙视了好久。 于是昨天我继续采用了这种自己18年前就曾经用过的排错方式: 1. 在可能引起bug的相关代码处逐一加上日志输出语句 2. 执行会出现bug的用户操作 3. 阅读AWS上生成的日志语句 上述三个步骤是一个不断迭代的过程。最开始我加了若干日志输出语句,执行操作后阅读生成的日志,发现没有任何异常。于是不断地增加新的日志打印代码,最后导致了执行一次操作,会生成1200行的日志输出。 我和负责前端开发的同事两人坐在显示器前,一行行检查这海量的日志输出。由于问题是用户第二次操作后才会暴露,每次操作会生成不同的会话,我们被迫不断的上下滑动屏幕来比较这两次会话的uuid和相关的WebSocket uuid等变量。Jerry很快发现,眼睛一眨不眨地盯着显示器逐条检查日志,时间一长眼睛就痛得受不了。无奈之下,只得把这些日志用打印机打印出来,用不同颜色的笔标注出两个会话对应的各种变量,在纸上来回比对。于是就有了下面这些纸张: 虽然最后用这种办法,成功排除了后台出错的可能性,使我们得以把精力花在前台代码的审查上,但是像我一个同事评价的,“这种方式太不环保了”,并且我自己也觉得,效率太低了。 后来好几位热心的同事告诉Jerry,就算运行在SAP Cloud Platform或者AWS这些云平台上的nodejs应用,也是可以单步调试的,Jerry Google了一下,发现远程调试确实很简单,就两条命令而已。 Jerry用我们创新空间团队另外一位同事Haytham开发并部署在AWS上的一个nodejs应用为例来尝试如何在我的本地电脑上对其进行调试。 Haytham虽然是一个大四本科生,但是已经在SAP成都研究院Jerry所在团队实习将近十个月的时间了,最近三个月一直在SAP德国总部参与一个项目的开发。 等Haytham回到成都后,会将自己这十个月的工作感悟,从一个SAP新人的视角给大家分享出来,敬请期待。 Haytham之前写过的文章: SAP成都研究院许聚龙:Hello, Coresystems! Haytham写的这个nodejs应用实际上是Github Webhook的一部分。我们在本地进行微服务nodejs开发,本地git客户端推送代码到远端github仓库。然后需要在AWS上手动git pull把最新的代码拉下来,再用一个开源工具pm2进行微服务部署。Haytham写的这个nodejs应用,能实现本地git推送完毕后一切后续流程的完全自动化,节省了我们大量的部署时间。 下面就来对Haytham这个运行在AWS上的nodejs应用进行远程调试。 1. 用node --inspect-brk在AWS上以调试模式启动应用。 之后控制台上的输出表明有一个nodejs进程以WebSocket协议在127.0.0.1:9229这个地址上监听调试客户端的连接。 2. 我在我的本地电脑上,用如下命令行将我本地电脑的端口9221映射到AWS调试进程监听的9229端口上: ssh -i C:Usersi042416.sshKOI.pem -L 9221:localhost:9229 ubuntu@ec2-us-east-2.compute.amazonaws.com 现在,本地电脑上Chrome浏览器地址栏chrome://inspect里指定监听地址为localhost:9221,  通过第二步建立的SSH tunnel, 我就可以用本地电脑连接到AWS上的nodejs应用并进行调试了。 现在终于可以在Chrome开发者工具里进行愉快的调试了: 因为我平时本地做nodejs开发和调试时,更喜欢用Visual Studio Code,所以下一步我准备试试用Visual Studio Code进行远程调试。 说到Visual Studio Code,Jerry突然想起今天在网上看到的一个关于这个IDE的有意思的扩展,名为"超越鼓励师"。 Jerry试着在自己的Visual Studio Code扩展安装栏里搜索了一下,这个扩展还真的可以下载。不过扩展里出现的"杨超越",Jerry又孤陋寡闻了,咨询了老婆后才知道她是谁。 至于实际效果如何,Jerry不做评价,欢迎Visual Studio Code爱好者自行下载体验。 ...

May 9, 2019 · 1 min · jiezi

调试和分析Python脚本

来源 | 愿码(ChainDesk.CN)内容编辑愿码Slogan | 连接每个程序员的故事网站 | http://chaindesk.cn愿码愿景 | 打造全学科IT系统免费课程,助力小白用户、初级工程师0成本免费系统学习、低成本进阶,帮助BAT一线资深工程师成长并利用自身优势创造睡后收入。官方公众号 | 愿码 | 愿码服务号 | 区块链部落免费加入愿码全思维工程师社群 | 任一公众号回复“愿码”两个字获取入群二维码本文阅读时长:11min调试和分析在Python开发中发挥重要作用 。调试器可帮助程序员分析完整的代码。调试器设置断点,而分析器运行我们的代码并向我们提供执行时间的详细信息,分析器将识别程序中的瓶颈。Python调试技术调试是一个解决代码中出现的问题并阻止软件正常运行的过程。在Python中,调试非常简单。Python调试器设置条件断点并一次调试一行源代码。我们将使用pdb Python标准库中的模块调试我们的Python脚本 。为了更好地调试Python程序,可以使用各种技术。我们将讨论Python调试的四种技术:print() 声明:这是了解发生了什么的最简单方法,因此您可以检查已执行的内容。logging:这就像一个print声明,但有更多的上下文信息,所以你可以完全理解它。pdb debugger:这是一种常用的调试技术。使用的优点pdb是您可以pdb从命令行,解释器和程序中使用。IDE调试器:IDE具有集成调试器。它允许开发人员执行他们的代码,然后开发人员可以在程序执行时进行检查。错误处理(异常处理)在本节中,我们将学习Python如何处理异常。例外是程序执行期间发生的错误。每当发生任何错误时,Python都会生成一个异常,该异常将使用try … except块进行处理。程序无法处理某些异常,因此会导致错误消息。现在,我们将看到一些异常示例。在终端中,启动 python3交互式控制台,我们将看到一些异常示例:student@ubuntu:$ python3Python 3.5.2 (default, Nov 23 2017, 16:37:01)[GCC 5.4.0 20160609] on linuxType “help”, “copyright”, “credits” or “license” for more information.>>>>>> 50 / 0Traceback (most recent call last): File “”, line 1, in ZeroDivisionError: division by zero>>>>>> 6 + abc*5Traceback (most recent call last): File “”, line 1, in NameError: name ‘abc’ is not defined>>>>>> ‘abc’ + 2Traceback (most recent call last): File “”, line 1, in TypeError: Can’t convert ‘int’ object to str implicitly>>>>>> import abcdTraceback (most recent call last): File “”, line 1, in ImportError: No module named ‘abcd’>>> 这些是例外的一些例子。现在,我们将看到我们如何处理异常。每当Python程序中发生错误时,都会引发异常。我们还可以使用raise关键字强制引发异常。现在我们将看到一个try…except处理异常的块。在try块中,我们将编写可能生成异常的代码。在except块中,我们将为该异常编写解决方案。语法 try…except如下:try: statement(s)except: statement(s)一个try块可以有多个except语句。我们也可以通过在except关键字后面输入例外名称来处理特定的例外。处理特定异常的语法如下:try: statement(s)except exception_name: statement(s)我们将创建一个exception_example.py 要捕获的脚本ZeroDivisionError。在脚本中编写以下代码:a = 35b = 57try: c = a + b print(“The value of c is: “, c) d = b / 0 print(“The value of d is: “, d) except: print(“Division by zero is not possible”) print(“Out of try…except block”)按如下所示运行脚本,您将获得以下输出:student@ubuntu:$ python3 exception_example.pyThe value of c is: 92Division by zero is not possibleOut of try…except block调试器工具Python支持许多调试工具:winpdbpydevpydbpdbgdbpyDebug在本节中,我们将学习pdb Python调试器。pdbmodule是Python标准库的一部分,始终可供使用。pdb调试器该pdb模块用于调试Python程序。Python程序使用pdb交互式源代码调试器来调试程序。pdb设置断点并检查堆栈帧,并列出源代码。现在我们将了解如何使用pdb调试器。有三种方法可以使用此调试器:· 在解释器中· 从命令行· 在Python脚本中我们将创建一个pdb_example.py脚本并在该脚本中添加以下内容:class Student: def init(self, std): self.count = std def print_std(self): for i in range(self.count): print(i) returnif name == ‘main’: Student(5).print_std()以此脚本为例学习Python调试,我们将看到如何详细启动调试器。在解释器中要从Python交互式控制台启动调试器,我们使用run()或runeval()。启动python3交互式控制台。运行以下命令以启动控制台:$ python3导入我们的 pdb_example脚本名称和pdb模块。现在,我们将使用run()并且我们将字符串表达式作为参数传递给run()Python解释器本身:student@ubuntu:$ python3Python 3.5.2 (default, Nov 23 2017, 16:37:01)[GCC 5.4.0 20160609] on linuxType “help”, “copyright”, “credits” or “license” for more information.>>>>>> import pdb_example>>> import pdb>>> pdb.run(‘pdb_example.Student(5).print_std()’)> (1)()(Pdb)要继续调试,请continue在(Pdb)提示符后输入并按Enter键。如果你想知道我们可以在这里使用的选项,那么在(Pdb)提示后按两次Tab 键。现在,输入后continue,我们将获得如下输出:student@ubuntu:$ python3Python 3.5.2 (default, Nov 23 2017, 16:37:01)[GCC 5.4.0 20160609] on linuxType “help”, “copyright”, “credits” or “license” for more information.>>>>>> import pdb_example>>> import pdb>>> pdb.run(‘pdb_example.Student(5).print_std()’)> (1)()(Pdb) continue01234>>> 从命令行运行调试器的最简单,最直接的方法是从命令行。我们的程序将作为调试器的输入。您可以从命令行使用调试器,如下所示:$ python3 -m pdb pdb_example.py从命令行运行调试器时,将加载源代码,它将停止在找到的第一行执行。输入continue以继续调试。这是输出:student@ubuntu:$ python3 -m pdb pdb_example.py> /home/student/pdb_example.py(1)()-> class Student:(Pdb) continue01234The program finished and will be restarted> /home/student/pdb_example.py(1)()-> class Student:(Pdb)在Python脚本中前两种技术将在Python程序开始时启动调试器。但这第三种技术最适合长期运行的流程。要在脚本中启动调试器,请使用set_trace()。现在,修改您的pdb_example.py 文件,如下所示:import pdbclass Student: def init(self, std): self.count = std def print_std(self): for i in range(self.count): pdb.set_trace() print(i) return if name == ‘main’: Student(5).print_std()现在,按如下方式运行程序:student@ubuntu:$ python3 pdb_example.py> /home/student/pdb_example.py(10)print_std()-> print(i)(Pdb) continue0> /home/student/pdb_example.py(9)print_std()-> pdb.set_trace()(Pdb)set_trace() 是一个Python函数,因此您可以在程序中的任何位置调用它。因此,这些是启动调试器的三种方式。调试基本程序崩溃在本节中,我们将看到跟踪模块。跟踪模块有助于跟踪程序执行。因此,每当您的Python程序崩溃时,我们都可以理解崩溃的位置。我们可以通过将跟踪模块导入您的脚本以及命令行来使用它。现在,我们将创建一个名为脚本trace_example.py并在脚本中编写以下内容:class Student: def init(self, std): self.count = std def go(self): for i in range(self.count): print(i) returnif name == ‘main’: Student(5).go()输出如下:student@ubuntu:$ python3 -m trace –trace trace_example.py — modulename: trace_example, funcname: trace_example.py(1): class Student: — modulename: trace_example, funcname: Studenttrace_example.py(1): class Student:trace_example.py(2): def init(self, std):trace_example.py(5): def go(self):trace_example.py(10): if name == ‘main’:trace_example.py(11): Student(5).go() — modulename: trace_example, funcname: inittrace_example.py(3): self.count = std — modulename: trace_example, funcname: gotrace_example.py(6): for i in range(self.count):trace_example.py(7): print(i)0trace_example.py(6): for i in range(self.count):trace_example.py(7): print(i)1trace_example.py(6): for i in range(self.count):trace_example.py(7): print(i)2trace_example.py(6): for i in range(self.count):trace_example.py(7): print(i)3trace_example.py(6): for i in range(self.count):trace_example.py(7): print(i)4因此,通过trace –trace在命令行使用,开发人员可以逐行跟踪程序。因此,只要程序崩溃,开发人员就会知道崩溃的实例。分析和计时程序分析Python程序意味着测量程序的执行时间。它衡量每个功能所花费的时间。Python的cProfile模块用于分析Python程序。cProfile模块如前所述,分析意味着测量程序的执行时间。我们将使用cProfile Python模块来分析程序。现在,我们将编写一个 cprof_example.py 脚本并在其中编写以下代码:mul_value = 0def mul_numbers( num1, num2 ): mul_value = num1 * num2; print (“Local Value: “, mul_value) return mul_valuemul_numbers( 58, 77 )print (“Global Value: “, mul_value)运行程序,您将看到如下输出:student@ubuntu:$ python3 -m cProfile cprof_example.pyLocal Value: 4466Global Value: 0 6 function calls in 0.000 seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) 1 0.000 0.000 0.000 0.000 cprof_example.py:1() 1 0.000 0.000 0.000 0.000 cprof_example.py:2(mul_numbers) 1 0.000 0.000 0.000 0.000 {built-in method builtins.exec} 2 0.000 0.000 0.000 0.000 {built-in method builtins.print} 1 0.000 0.000 0.000 0.000 {method ‘disable’ of ‘_lsprof.Profiler’ objects}因此,使用时cProfile,所有被调用的函数都将打印出每个函数所花费的时间。现在,我们将看到这些列标题的含义:· ncalls: 通话次数· tottime: 在给定函数中花费的总时间· percall:商数tottime除以ncalls· cumtime:在此和所有方面花费的累计时间 subfunctions· percall:cumtime除以原始调用的商数· filename:lineno(function):提供每个功能的相应数据timeittimeit是一个Python模块,用于计算Python脚本的一小部分。您可以从命令行调用timeit,也可以将timeit模块导入到脚本中。我们将编写一个脚本来计算一段代码。创建一个timeit_example.py脚本并将以下内容写入其中:import timeitprg_setup = “from math import sqrt"prg_code = ‘‘‘def timeit_example(): list1 = [] for x in range(50): list1.append(sqrt(x))’’’# timeit statementprint(timeit.timeit(setup = prg_setup, stmt = prg_code, number = 10000))使用timeit,我们可以决定我们要测量的代码片段。因此,我们可以轻松定义设置代码以及我们要单独执行测试的代码段。主代码运行100万次,这是默认时间,而设置代码只运行一次。使程序运行得更快有多种方法可以使Python程序运行得更快,例如:描述您的代码,以便识别瓶颈使用内置函数和库,因此解释器不需要执行循环避免使用全局变量,因为Python在访问全局变量时非常慢使用现有包 ...

April 9, 2019 · 3 min · jiezi

Core dump调试小记(暂时未解决)

缘起现场的故障,让我支持一下。过程第一次通过简易的日志,定位到了函数文件,远程连到现场环境,直接gdb进程名,一直到函数return,都没有core掉。干得比较仓促,都没有再看看相关函数第二次吃完饭,睡过觉后,继续定位,毕竟现场的优先级高啊。跟人沟通后,get到两点思路,让现场确认一下1、看下.config的CLTSERVID的值和链路的值是不是不样,确认后都是26。2、调高日志级别,原来是0(只显示错误的),让现场改成3,最高可支持9。这个后期得了解一下第一次,我没有找到生成的core文件,也就没管,直接gdb了,后面就看了一下。linux下生成core dump文件方法及设置ulimit -c如果是0,则无法生成core dump,当然也可以用ulimit -a查看。用ulimit -c 2048去设置core的大小让现场试了以上三招后,重新跑个进程,捞个日志来看看的,给我截图说这个错“ORA-00257: archiver error. Connect internal only, until freed ”,是现场的生产环境连接不上库了,于是再次挂起。最后参考段错误调试神器 - Core Dump详解关于ORA-00257: archiver error. Connect internal only, until freed 错误的处理方法履历20190212遇到的问题,写了第一次、第二次。

February 12, 2019 · 1 min · jiezi

使用 VSCode 调试 Koa 或者 Express 项目

前言平常调试 node 打 log 打习惯了,突然发现一个问题就是打印对象的时候,尤其这个对象里面有很多属性的时候,在终端上得一直往上拉才能看到,因此打算使用 vscode 来打断点调试程序。安装这里的例子是使用 koa ,express 类似。我是使用阿里巴巴的飞冰快速搭建一个后台和前台的项目。下载飞冰打开飞冰,使用ICE Design Pro模板并点击 添加koa2,如下自动安装完成后,使用 vscode 打开项目:打开终端,运行npm run client 这个时候前端项目就运行起来了。稍微修改一下前端的代码,因为这个模板默认是使用前端直接返回数据,而不去请求接口,打开client/pages/UserLogin/actions.js,将 import {login} from ‘../../api/user’;改为 import {login} from ‘../../api/index’;就可以了。最后打开页面,地址终端里面有说明。编写launch.jsonVsCode左侧第四个按钮是调试按钮,默认是『没有配置』。点击右侧的齿轮状图标,选择Node.js 会在项目根目录下创建 .vscode 的文件夹及 launch.json 文件。launch.json 内容如下:{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 “version”: “0.2.0”, “configurations”: [ { “type”: “node”, “request”: “launch”, “name”: “启动程序”, “program”: “${workspaceFolder}/server/index.js” } ]}默认会访问server下的 index.js 文件,但是这个项目的入口文件是 app.js,因此需要将index.js改为app.js。在launch.json中会使用到一些预定变量,这里说明一下:${workspaceRoot}:VSCode中打开文件夹的路径${workspaceRootFolderName}:VSCode中打开文件夹的路径, 但不包含"/"${file}:当前打开的文件${fileBasename}: 当前打开文件的文件名, 不含扩展名${fileDirname}: 当前打开文件的目录名${fileExtname} 当前打开文件的扩展名${cwd}:当前执行目录当我们在单步调试程序的时候,会进入node_modules里面,通常情况下我们并不需要去关心里面的逻辑实现,只关心项目本身的代码。在这个时候,我们就需要使用skipFiles:{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 “version”: “0.2.0”, “configurations”: [{ “type”: “node”, “request”: “launch”, “name”: “启动程序”, “program”: “${workspaceFolder}/server/index.js”, “skipFiles”: [ “${workspaceRoot}/node_modules//*.js”, “<node_internals>//.js” ] }]}我们还想要自动重启的功能,安装 nodemon 或者 node-dev:// 任选其一npm i nodemon -gnpm i node-dev -g修改lanuch.json:{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 “version”: “0.2.0”, “configurations”: [{ “type”: “node”, “request”: “launch”, “name”: “启动程序”, “program”: “${workspaceFolder}/server/index.js”, “runtimeExecutable”: “nodemon”, // 或者 node-dev “restart”: true, “console”: “integratedTerminal”, “skipFiles”: [ “${workspaceRoot}/node_modules/**/.js”, “<node_internals>/**/*.js” ] }]}这里新增了三个字段,分别是:runtimeExecutable:用什么命令执行 app.js,这里设置为 nodemon,默认是 noderestart:在终止 Node.js 后重启会话console:启动调试目标的位置,这里选择在 vscode 的集成终端输出信息调试这里在 server/controller/user.js 的 login 打了个断点:启动调试,如下:vscode 集成终端打印如下:在前端页面点击登录,会跳到这里:我们就能看到变量的信息啦????(注意:如果此时终止了调试,nodemon 还是会运行,得在集成终端终止) ...

December 31, 2018 · 1 min · jiezi

Vue调试神器之Vue.js devTools

Vue项目中使用Vue.js devTools这款调试神器,可以极大程度的提高我们的开发效率。安装1、打开Chrome网上应用商店安装插件(自墙),直接搜索devTools安装即可。贵宾传送阵,请戳这里→Chrome网上应用商店2、从github上下载到本地。贵宾传送阵,请戳这里→vue-devtools1)、进入到/vue-devtools目录下(npm install或者cnpm install)安装项目所需依赖。2)、安装完依赖后(npm run build或者cnpm run build)编译项目。3)、编译完项目后,在/vue-devtools/shell/chrome/manifest.json中修改persistent参数false为true。4)、在chrome扩展程序页面,打开“开发者模式”,点击“加载已解压的扩展程序”按钮,选择你本地的…/vue-devtools/shell/chrome文件夹, 添加完成后,勾选允许文件地址是否访问。安装完成后devTools的图标会出现在浏览器的菜单栏中。以上两种安装方式告一段落。下面让我们在vue项目中体验一下这款调试神器吧。使用运行Vue项目,在Chrome浏览器中展示项目(浏览器菜单栏中的devTools图标会亮起),按F12打开开发者工具,在开发者工具的菜单栏最后面会看到Vue,选中它就可以尽情的使用了。当然这样一顿行云流水的操作下来,有些人会一次成功,而有些人则不会成功,浏览器菜单中的devTools图标亮滴鸭批,但是就是在开发者工具的菜单栏最后面看不到Vue。嗯~~~,怎么肥事小老弟?请查看项目的index.html中,对vue.js的引用。你肯定使用了压缩版的vue.min.js,使用vue.min.js默认为生产环境,会导致devTools不显示,改为vue.js即可。

November 29, 2018 · 1 min · jiezi