十六、代码校验(4)

news2024/11/24 9:15:14

本章概要

  • 调试
    • 使用 JDB 调试
    • 图形化调试器

调试

尽管聪明地使用 System.out 或日志信息能给我们带来对程序行为的有效见解,但对于困难问题来说,这种方式就显得笨拙且耗时了。

你也可能需要更加深入地理解程序,仅依靠打印日志做不到。此时你需要调试器。除了比打印语句更快更轻易地展示信息以外,调试器还可以设置断点,并在程序运行到这些断点处暂停程序。

使用调试器,可以展示任何时刻的程序状态,查看变量的值,一步一步运行程序,连接远程运行的程序等等。特别是当你构建较大规模的系统(bug 容易被掩埋)时,熟练使用调试器是值得的。

使用 JDB 调试

Java 调试器(JDB)是 JDK 内置的命令行工具。从调试的指令和命令行接口两方面看的话,JDB 至少从概念上是 GNU 调试器(GDB,受 Unix DB 的影响)的继承者。JDB 对于学习调试和执行简单的调试任务来说是有用的,而且知道只要安装了 JDK 就可以使用 JDB 是有帮助的。然而,对于大型项目来说,你可能想要一个图形化的调试器,这在后面会描述。

假设你写了如下程序:

// validating/SimpleDebugging.java
// {ThrowsException}
public class SimpleDebugging {
    private static void foo1() {
        System.out.println("In foo1");
        foo2();
    }

    private static void foo2() {
        System.out.println("In foo2");
        foo3();
    }

    private static void foo3() {
        System.out.println("In foo3");
        int j = 1;
        j--;
        int i = 5 / j;
    }

    public static void main(String[] args) {
        foo1();
    }
}

在这里插入图片描述

首先看方法 foo3(),问题很明显:除数是 0。但是假如这段代码被埋没在大型程序中(像这里的调用序列暗示的那样)而且你不知道从哪儿开始查找问题。结果呢,异常会给出足够的信息让你定位问题。然而,假设事情更加复杂,你必须更加深入程序中来获得比异常提供的更多的信息。

为了运行 JDB,你需要在编译 SimpleDebugging.java 时加上 -g 标记,从而告诉编译器生成编译信息。然后使用如下命令开始调试程序:

jdb SimpleDebugging

接着 JDB 就会运行,出现命令行提示。你可以输入 ? 查看可用的 JDB 命令。

这里展示了如何使用交互式追踪一个问题的调试历程:

Initializing jdb…

> catch Exception

> 表明 JDB 在等待输入命令。命令 catch Exception 在任何抛出异常的地方设置断点(然而,即使你不显式地设置断点,调试器也会停止— JDB 中好像是默认在异常抛出处设置了异常)。接着命令行会给出如下响应:

Deferring exception catch Exception.

It will be set after the class is loaded.

继续输入:

> run

现在程序将运行到下个断点处,在这个例子中就是异常发生的地方。下面是运行 run 命令的结果:

run SimpleDebugging

Set uncaught java.lang.Throwable

Set deferred uncaught java.lang.Throwable

>

VM Started: In foo1

In foo2

In foo3

Exception occurred: java.lang.ArithmeticException

(uncaught)“thread=main”,

SimpleDebugging.foo3(),line=16 bci=15

16 int i = 5 / j

程序运行到第16行时发生异常,但是 JDB 在异常发生时就不复存在。调试器还展示了是哪一行导致了异常。你可以使用 list 将导致程序终止的执行点列出来:

main[1] list

12 private static void foo3() {

13 System.out.println(“In foo3”);

14 int j = 1;

15 j–;

16 => int i = 5 / j;

17 }

18 public static void main(String[] args) {

19 foo1();

20 }

21 }

**/_ Output:_

上述 => 展示了程序将继续运行的执行点。你可以使用命令 cont(continue) 继续运行,但是会导致 JDB 在异常发生时退出并打印出栈轨迹信息。

命令 locals 能转储所有的局部变量值:

main[1] locals

Method arguments:

Local variables:

j = 0

命令 wherei 打印进入当前线程的方法栈中的栈帧信息:

main[1] wherei

[1] SimpleDebugging.foo3(SimpleDebugging.java:16), pc =15

[2] SimpleDebugging.foo2(SimpleDebugging.java:10), pc = 8

[3] SimpleDebugging.foo1(SimpleDebugging.java:6), pc = 8

[4] SimpleDebugging.main(SimpleDebugging.java:19), pc = 10

wherei 后的每一行代表一个方法调用和调用返回点(由程序计数器显示数值)。这里的调用序列是 main(), foo1(), foo2()foo3()

因为命令 list 展示了执行停止的地方,所以你通常有足够的信息得知发生了什么并修复它。命令 help 将会告诉你更多关于 jdb 的用法,但是在花更多的时间学习它之前必须明白命令行调试器往往需要花费更多的精力得到结果。使用 jdb 学习调试的基础部分,然后转而学习图形界面调试器。

图形化调试器

使用类似 JDB 的命令行调试器是不方便的。它需要显式的命令去查看变量的状态(locals, dump),列出源代码中的执行点(list),查找系统中的线程(threads),设置断点(stop in, stop at)等等。使用图形化调试器只需要点击几下,不需要使用显式的命令就能使用这些特性,而且能查看被调试程序的最新细节。

因此,尽管你可能一开始用 JDB 尝试调试,但是你将发现使用图形化调试器能更加高效、更快速地追踪 bug。IBM 的 Eclipse,Oracle 的 NetBeans 和 JetBrains 的 IntelliJ 这些集成开发环境都含有面向 Java 语言的好用的图形化调试器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1091074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【牛客面试必刷TOP101】Day8.BM33 二叉树的镜像和BM36 判断是不是平衡二叉树

作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:牛客面试必刷TOP101 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!&…

2015架构案例(五十一)

第5题 【说明】某信息技术公司计划开发一套在线投票系统,用于为市场调研、信息调查和销售反馈等业务提供服务。该系统计划通过大量宣传和奖品鼓励的方式快速积累用户,当用户规模扩大到一定程度时,开始联系相关企业提供信息服务,并…

关于RNNoise、webrtc_ns、三角带通滤波器、对数能量

语音特征参数MFCC提取过程详解 其中讲解了:三角带通滤波器 、计算每个滤波器组输出的对数能量、对数能量、经离散余弦变换(DCT)得到MFCC系数 推荐阅读某乎这位大佬的全部文章: 下面是几篇出自这位大佬的很好的文章: …

MySQL进阶(回望MySQL)——从数据资产谈起 MySQL的DOS命令、常用数据类型、SQL语句的分类 SQL函数

前言 SQL(Structured Query Language)是一种用于管理关系型数据库的标准化语言,它用于定义、操作和管理数据库中的数据。SQL是一种通用的语言,可以用于多种关系型数据库管理系统(RDBMS),如MySQ…

小程序需带参数跳转

1、需要生成二维码的数据 直接在浏览器中替换成自己的appid,secret及可生成一个access_token https://api.weixin.qq.com/cgi-bin/token?grant_typeclient_credential&appidwxxxxx&secretxxxxx用access_token https://api.weixin.qq.com/wxa/getwxacode…

【LeetCode热题100】--215.数组中的第K个最大元素

215.数组中的第K个最大元素 本题主要是返回数组排序之后的倒数第k个位置 方法一:基于快速排序 思路和算法 我们可以用快速排序来解决这个问题,先对原数组排序,再返回倒数第 k 个位置,这样平均时间复杂度是 O(nlog⁡n)&#xff0…

管程的介绍

一、概述 1.引入原因 信号量机制实现同步存在编写程序困难,易出错问题 2.概念 是一种实现进程互斥与同步的机制, 3.组成 共享数据结构说明、对数据结构操作的过程/函数、初始化共享数据、管程名; 4.特点 类似类的结构(数据对象相关操…

IDEA通过Docker插件部署SpringBoot项目

1、配置Docker远程连接端口 找到并编辑服务器上的docker.service文件。 vim /usr/lib/systemd/system/docker.service在下面ExecStart替换成下面的 ExecStart/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock2.重启docker systemctl daemon-reload s…

强化学习(Reinforcement Learning)与策略梯度(Policy Gradient)

写在前面:本篇博文的内容来自李宏毅机器学习课程与自己的理解,同时还参考了一些其他博客(懒得放链接)。博文的内容主要用于自己学习与记录。 1 强化学习的基本框架 强化学习(Reinforcement Learning, RL)主要由智能体(Agent/Actor)、环境(Environment)、…

CSS padding(填充)

CSS padding(填充)是一个简写属性,定义元素边框与元素内容之间的空间,即上下左右的内边距。 padding(填充) 当元素的 padding(填充)内边距被清除时,所释放的区域将会受到…

最新Base64注入攻击和代码分析技术

点击星标,即时接收最新推文 本文选自《web安全攻防渗透测试实战指南(第2版)》 点击图片五折购书 Base64注入攻击 Base64注入攻击的测试地址在本书第2章。 从URL中可以看出,参数ID经过Base64编码(“%3d”是“”的URL编码…

Vulnhub系列靶机-Raven2

文章目录 Raven2 渗透测试1. 信息收集1.1 主机探测1.2 端口扫描1.3 目录爆破 2. 漏洞探测3. 漏洞利用3.1 msfconsole3.2 交互式shell 4. 权限提升 Raven2 渗透测试 1. 信息收集 1.1 主机探测 arp-scan -l1.2 端口扫描 nmap -p- -A 192.168.188.213通过nmap工具进行端口扫描…

LeetCode【54】螺旋矩阵

题目&#xff1a; 思路&#xff1a; 参考&#xff1a;https://blog.csdn.net/ShiXiAoLaNga/article/details/124975293 上下左右&#xff0c;四个游标&#xff0c;代表边界&#xff0c;每次遍历完一行或一列都移动游标&#xff1b;直到 down > up、right < left&#xf…

使用hugging face开源库accelerate进行多GPU(单机多卡)训练卡死问题

目录 问题描述及配置网上资料查找1.tqdm问题2.dataloader问题3.model(input)写法问题4.环境变量问题 我的卡死问题解决方法 问题描述及配置 在使用hugging face开源库accelerate进行多GPU训练&#xff08;单机多卡&#xff09;的时候&#xff0c;经常出现如下报错 [E Process…

key value存储到底有什么优势?

昨天被问到Key value存储到底有什么优势&#xff0c;当然脑子也没太转过来。正好昨天学习了B树和LSM树的差别&#xff0c;并了解到LSM树底层是可以用sstable来实现的。sstable包含一个数据块列表和一个索引块&#xff0c;数据块存储有序键镇对&#xff0c;索引块存储所有数据块…

navicate安装教程

Navicat是一款数据库管理工具&#xff0c;它支持多种数据库类型&#xff0c;包括MySQL、MariaDB、Oracle、SQL Server等。Navicat具有直观的图形用户界面和易于使用的功能&#xff0c;可以让用户轻松地管理和操作数据库。 首先&#xff0c;Navicat提供了一种简单的方法来连接到…

Linux gcc和make学习

文章目录 GCCgcc的安装gcc的工作流程 makefilemakefile的规则工作原理自动生成makefile的变量自定义变量预定义变量自动变量 模式匹配函数wildcard函数patsubst函数 伪声明 GCC gcc全程是&#xff08;GNU compiler collection CNU编译器套件&#xff09;&#xff0c;是由GNU开发…

【汇编语言学习笔记】一、基础知识

引言 汇编语言是直接在硬件之上工作的编程语言&#xff0c;首先要了解硬件系统的结构&#xff0c;才能有效的应用汇编语言对其编程。 1.1机器语言 机器语言是机器指令的集合。 机器指令展开来讲就是一台机器可以正确执行的命令。 1.2汇编语言 汇编语言的主体是汇编指令。 …

2023年中国特高压绝缘子市场规模及特高压投资完成额统计[图]

绝缘子指一般由固体绝缘材料制成&#xff0c;安装在不同点位的导体之间或导体与接地构件之间&#xff0c;是同时起到电气绝缘和机械支撑作用的器件&#xff0c;绝缘子可分为瓷绝缘子、玻璃绝缘子与复合绝缘子。特高压绝缘子指用于交流1,000kV、直流800kV及以上电压等级的绝缘子…

基于SSM框架的安全教育平台

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…