万本电子书0元读

万本电子书0元读

顶部广告

软件调试(第2版)卷1:硬件基础电子书

1. 软件调试领域的“百科全书”,围绕软件调试的“生态”系统(ecosystem)、异常(exception)和调试器三条主线,介绍软件调试的相关原理和机制,探讨可调试性(debuggability)的内涵、意义,以及实现软件可调试性的原则和方法,总结软件调试的方法和技巧; 2. 设有“格物致知”实践环节,提供配套资源,可供读者动手实践; 3. 丰富的行业背景知识和人文故事,让读者体验技术的有血有肉、有感情有温度。

售       价:¥

纸质售价:¥93.20购买纸书

393人正在读 | 1人评论 6.2

作       者:张银奎

出  版  社:人民邮电出版社

出版时间:2018-12-01

字       数:49.8万

所属分类: 科技 > 计算机/网络 > 软件系统

温馨提示:此类商品不支持退换货,不支持下载打印

为你推荐

  • 读书简介
  • 目录
  • 累计评论(1条)
  • 读书简介
  • 目录
  • 累计评论(1条)
本书堪称是软件调试的“百科全书”。作者围绕软件调试的“生态”系统(ecosystem)、异常(exception)和调试器 3 条主线,介绍软件调试的相关原理和机制,探讨可调试性(debuggability)的内涵、意义以及实现软件可调试性的原则和方法,总结软件调试的方法和技巧。 第1卷主要围绕硬件技术展介绍。全书分为4篇,共16章。*篇“绪论”(第1章),介绍了软件调试的概念、基本过程、分类和简要历史,并综述了本书后面将详细介绍的主要调试技术。第二篇“CPU及其调试设施”(第2~7章),以英特尔和ARM架构的CPU为例系统描述了CPU的调试支持。第三篇“GPU及其调试设施”(第8~14章),深探讨了Nvidia、AMD、英特尔、ARM和Imagination 这五大厂商的GPU。第四篇“可调试性”(第15~16章),介绍了提高软件可调试性的意义、基本原则、实例和需要注意的问题,并讨论了如何在软件发实践中实现可调试性。 本书理论与实践紧密结合,既涵盖了相关的技术背景知识,又针对大量具有代表性和普遍意义的技术细节行了讨论,是学习软件调试技术的宝贵资料。本书适合所有从事软件发工作的读者阅读,特别适合从事软件发、测试、支持的技术人员,从事反病毒、网络安全、版权保护等工作的技术人员,以及高等院校相关专业的教师和学生学习参考。 本书堪称是软件调试的“百科全书”。作者围绕软件调试的“生态”系统(ecosystem)、异常(exception)和调试器 3 条主线,介绍软件调试的相关原理和机制,探讨可调试性(debuggability)的内涵、意义以及实现软件可调试性的原则和方法,总结软件调试的方法和技巧。 第1卷主要围绕硬件技术展介绍。全书分为4篇,共16章。*篇“绪论”(第1章),介绍了软件调试的概念、基本过程、分类和简要历史,并综述了本书后面将详细介绍的主要调试技术。第二篇“CPU及其调试设施”(第2~7章),以英特尔和ARM架构的CPU为例系统描述了CPU的调试支持。第三篇“GPU及其调试设施”(第8~14章),深探讨了Nvidia、AMD、英特尔、ARM和Imagination 这五大厂商的GPU。第四篇“可调试性”(第15~16章),介绍了提高软件可调试性的意义、基本原则、实例和需要注意的问题,并讨论了如何在软件发实践中实现可调试性。 本书理论与实践紧密结合,既涵盖了相关的技术背景知识,又针对大量具有代表性和普遍意义的技术细节行了讨论,是学习软件调试技术的宝贵资料。本书适合所有从事软件发工作的读者阅读,特别适合从事软件发、测试、支持的技术人员,从事反病毒、网络安全、版权保护等工作的技术人员,以及高等院校相关专业的教师和学生学习参考。
【推荐语】
1. 软件调试领域的“百科全书”,围绕软件调试的“生态”系统(ecosystem)、异常(exception)和调试器三条主线,介绍软件调试的相关原理和机制,探讨可调试性(debuggability)的内涵、意义,以及实现软件可调试性的原则和方法,总结软件调试的方法和技巧; 2. 设有“格物致知”实践环节,提供配套资源,可供读者动手实践; 3. 丰富的行业背景知识和人文故事,让读者体验技术的有血有肉、有感情有温度。 第2版卷1新增内容如下: ·关于CPU增加了ARM处理器的相关内容; ·关于操作系统增加了Linux系统的相关内容; ·关于编译器增加了GCC的相关内容; ·关于调试器增加了GDB的相关内容; ·增加了全新的GPU内容。
【作者】
张银奎,国内知名的调试技术专家。毕业于上海交通大学信息与控制工程系,长期从事软件发和研究工作,曾在英特尔工作13 年,对 IA-32 架构、操作系统内核、驱动程序,尤其是对软件调试有较深的研究。著有《软件调试》《格蠹汇编》等畅销、常销技术图书, 格蠹科技(xedge.ai) 创始人,高端调试网站(advdbg.org)创建者。翻译(合译)作品有《二十一世纪机器人》《观止——微软创建NT和未来的夺命狂奔》《数据挖掘原理》《机器学习》《人工智能:复杂问题求解的结构和策略》等。
目录展开

内容提要

历史回眸

第2版前言

第1版前言

资源与支持

第一篇 绪 论

第1章 软件调试基础

1.1 简介

1.1.1 定义

1.1.2 基本过程

1.2 基本特征

1.2.1 难度大

1.2.2 难以估计完成时间

1.2.3 广泛的关联性

1.3 简要历史

1.3.1 单步执行

1.3.2 断点指令

1.3.3 分支监视

1.4 分类

1.4.1 按调试目标的系统环境分类

1.4.2 按目标代码的执行方式分类

1.4.3 按目标代码的执行模式分类

1.4.4 按软件所处的阶段分类

1.4.5 按调试器与调试目标的相对位置分类

1.4.6 按调试目标的活动性分类

1.4.7 按调试工具分类

1.5 调试技术概览

1.5.1 断点

1.5.2 单步执行

1.5.3 输出调试信息

1.5.4 日志

1.5.5 事件追踪

1.5.6 转储文件

1.5.7 栈回溯

1.5.8 反汇编

1.5.9 观察和修改内存数据

1.5.10 控制被调试进程和线程

1.6 错误与缺欠

1.6.1 内因与表象

1.6.2 谁的bug

1.6.3 bug的生命周期

1.6.4 软件错误的开支曲线

1.7 重要性

1.7.1 调试与编码的关系

1.7.2 调试与测试的关系

1.7.3 调试与逆向工程的关系

1.7.4 学习调试技术的意义

1.7.5 调试技术尚未得到应有的重视

1.8 本章小结

参考资料

第二篇 CPU及其调试设施

第2章 CPU基础

2.1 指令和指令集

2.1.1 基本特征

2.1.2 寻址方式

2.1.3 指令的执行过程

2.2 英特尔架构处理器

2.2.1 80386处理器

2.2.2 80486处理器

2.2.3 奔腾处理器

2.2.4 P6系列处理器

2.2.5 奔腾4处理器

2.2.6 Core 2系列处理器

2.2.7 Nehalem微架构

2.2.8 Sandy Bridge微架构

2.2.9 Ivy Bridge微架构

2.2.10 Haswell微架构

2.2.11 Broadwell微架构

2.2.12 Skylake微架构

2.2.13 Kaby Lake微架构

2.3 CPU的操作模式

2.4 寄存器

2.4.1 通用数据寄存器

2.4.2 标志寄存器

2.4.3 MSR寄存器

2.4.4 控制寄存器

2.4.5 其他寄存器

2.4.6 64位模式时的寄存器

2.5 理解保护模式

2.5.1 任务间的保护机制

2.5.2 任务内的保护

2.5.3 特权级

2.5.4 特权指令

2.6 段机制

2.6.1 段描述符

2.6.2 描述符表

2.6.3 段选择子

2.6.4 观察段寄存器

2.7 分页机制

2.7.1 32位经典分页

2.7.2 PAE分页

2.7.3 IA-32e分页

2.7.4 大内存页

2.7.5 WinDBG的有关命令

2.8 PC系统概貌

2.9 ARM架构基础

2.9.1 ARM的多重含义

2.9.2 主要版本

2.9.3 操作模式和状态

2.9.4 32位架构核心寄存器

2.9.5 协处理器

2.9.6 虚拟内存管理

2.9.7 伪段支持

2.9.8 64位ARM架构

2.10 本章小结

参考资料

第3章 中断和异常

3.1 概念和差异

3.1.1 中断

3.1.2 异常

3.1.3 比较

3.2 异常的分类

3.2.1 错误类异常

3.2.2 陷阱类异常

3.2.3 中止类异常

3.3 异常例析

3.3.1 列表

3.3.2 错误代码

3.3.3 示例

3.4 中断/异常的优先级

3.5 中断/异常处理

3.5.1 实模式

3.5.2 保护模式

3.5.3 IA-32e模式

3.6 ARM架构中的异常机制

3.7 本章小结

参考资料

第4章 断点和单步执行

4.1 软件断点

4.1.1 INT 3

4.1.2 在调试器中设置断点

4.1.3 断点命中

4.1.4 恢复执行

4.1.5 特殊用途

4.1.6 断点API

4.1.7 系统对INT 3的优待

4.1.8 观察调试器写入的INT 3指令

4.1.9 归纳和提示

4.2 硬件断点

4.2.1 调试寄存器概览

4.2.2 调试地址寄存器

4.2.3 调试控制寄存器

4.2.4 指令断点

4.2.5 调试异常

4.2.6 调试状态寄存器

4.2.7 示例

4.2.8 硬件断点的设置方法

4.2.9 归纳

4.3 陷阱标志

4.3.1 单步执行标志

4.3.2 高级语言的单步执行

4.3.3 任务状态段陷阱标志

4.3.4 按分支单步执行标志

4.4 实模式调试器例析

4.4.1 Debug.exe

4.4.2 8086 Monitor

4.4.3 关键实现

4.5 反调试示例

4.6 ARM架构的断点支持

4.6.1 断点指令

4.6.2 断点寄存器

4.6.3 监视点寄存器

4.6.4 单步跟踪

4.7 本章小结

参考资料

第5章 分支记录和性能监视

5.1 分支监视概览

5.2 使用寄存器的分支记录

5.2.1 LBR

5.2.2 LBR栈

5.2.3 示例

5.2.4 在Windows操作系统中的应用

5.3 使用内存的分支记录

5.3.1 DS区

5.3.2 启用DS机制

5.3.3 调试控制寄存器

5.4 DS示例:CpuWhere

5.4.1 驱动程序

5.4.2 应用界面

5.4.3 2.0版本

5.4.4 局限性和扩展建议

5.4.5 Linux内核中的BTS驱动

5.5 性能监视

5.5.1 奔腾处理器的性能监视机制

5.5.2 P6处理器的性能监视机制

5.5.3 P4处理器的性能监视

5.5.4 架构性的性能监视机制

5.5.5 酷睿微架构处理器的性能监视机制

5.5.6 资源

5.6 实时指令追踪

5.6.1 工作原理

5.6.2 RTIT数据包

5.6.3 Linux支持

5.7 ARM架构的性能监视设施

5.7.1 PMUv1和PMUv2

5.7.2 PMUv3

5.7.3 示例

5.7.4 CoreSight

5.8 本章小结

参考资料

第6章 机器检查架构

6.1 奔腾处理器的机器检查机制

6.2 MCA

6.2.1 概览

6.2.2 MCA的全局寄存器

6.2.3 MCA的错误报告寄存器

6.2.4 扩展的机器检查状态寄存器

6.2.5 MCA错误编码

6.3 编写MCA软件

6.3.1 基本算法

6.3.2 示例

6.3.3 在Windows系统中的应用

6.3.4 在Linux系统中的应用

6.4 本章小结

参考资料

第7章 JTAG调试

7.1 简介

7.1.1 ICE

7.1.2 JTAG

7.2 JTAG原理

7.2.1 边界扫描链路

7.2.2 TAP信号

7.2.3 TAP寄存器

7.2.4 TAP控制器

7.2.5 TAP指令

7.3 JTAG应用

7.3.1 JTAG调试

7.3.2 调试端口

7.4 IA处理器的JTAG支持

7.4.1 P6处理器的JTAG实现

7.4.2 探测模式

7.4.3 ITP接口

7.4.4 XDP端口

7.4.5 ITP-XDP调试仪

7.4.6 直接连接接口

7.4.7 典型应用

7.5 ARM处理器的JTAG支持

7.5.1 ARM调试接口

7.5.2 调试端口

7.5.3 访问端口

7.5.4 被调试器件

7.5.5 调试接插口

7.5.6 硬件调试器

7.5.7 DS-5

7.6 本章小结

参考资料

第三篇 GPU及其调试设施

第8章 GPU基础

8.1 GPU简史

8.1.1 从显卡说起

8.1.2 硬件加速

8.1.3 可编程和通用化

8.1.4 三轮演进

8.2 设备身份

8.2.1 “喂模式”

8.2.2 内存复制

8.2.3 超时检测和复位

8.2.4 与CPU之并立

8.3 软件接口

8.3.1 设备寄存器

8.3.2 批命令缓冲区

8.3.3 状态模型

8.4 GPU驱动模型

8.4.1 WDDM

8.4.2 DRI和DRM

8.5 编程技术

8.5.1 着色器

8.5.2 Brook和CUDA

8.5.3 OpenCL

8.6 调试设施

8.6.1 输出调试信息

8.6.2 发布断点

8.6.3 其他断点

8.6.4 单步执行

8.6.5 观察程序状态

8.7 本章小结

参考资料

第9章 Nvidia GPU及其调试设施

9.1 概要

9.1.1 一套微架构

9.1.2 三条产品线

9.1.3 封闭

9.2 微架构

9.2.1 G80(特斯拉1.0微架构)

9.2.2 GT200(特斯拉2.0微架构)

9.2.3 GF100(费米微架构)

9.2.4 GK110(开普勒微架构)

9.2.5 GM107(麦斯威尔微架构)

9.2.6 GP104(帕斯卡微架构)

9.2.7 GV100(伏特微架构)

9.2.8 持续改进

9.3 硬件指令集

9.3.1 SASS

9.3.2 指令格式

9.3.3 谓词执行

9.3.4 计算能力

9.3.5 GT200的指令集

9.3.6 GV100的指令集

9.4 PTX指令集

9.4.1 汇编和反汇编

9.4.2 状态空间

9.4.3 虚拟寄存器

9.4.4 数据类型

9.4.5 指令格式

9.4.6 内嵌汇编

9.5 CUDA

9.5.1 源于Brook

9.5.2 算核

9.5.3 执行配置

9.5.4 内置变量

9.5.5 Warp

9.5.6 显式并行

9.6 异常和陷阱

9.6.1 陷阱指令

9.6.2 陷阱后缀

9.6.3 陷阱处理

9.7 系统调用

9.7.1 vprintf

9.7.2 malloc和free

9.7.3 __assertfail

9.8 断点指令

9.8.1 PTX的断点指令

9.8.2 硬件的断点指令

9.9 Nsight的断点功能

9.9.1 源代码断点

9.9.2 函数断点

9.9.3 根据线程组和线程编号设置条件断点

9.10 数据断点

9.10.1 设置方法

9.10.2 命中

9.10.3 数量限制

9.10.4 设置时机

9.11 调试符号

9.11.1 编译选项

9.11.2 ELF载体

9.11.3 DWARF

9.12 CUDA GDB

9.12.1 通用命令

9.12.2 扩展

9.12.3 局限

9.13 CUDA调试器API

9.13.1 头文件

9.13.2 调试事件

9.13.3 工作原理

9.14 本章小结

参考资料

第10章 AMD GPU及其调试设施

10.1 演进简史

10.1.1 三个发展阶段

10.1.2 两种产品形态

10.2 Terascale微架构

10.2.1 总体结构

10.2.2 SIMD核心

10.2.3 VLIW

10.2.4 四类指令

10.3 GCN微架构

10.3.1 逻辑结构

10.3.2 CU和波阵

10.3.3 内存层次结构

10.3.4 工作组

10.3.5 多执行引擎

10.4 GCN指令集

10.4.1 7种指令类型

10.4.2 指令格式

10.4.3 不再是VLIW指令

10.4.4 指令手册

10.5 编程模型

10.5.1 地幔

10.5.2 HSA

10.5.3 ROCm

10.5.4 Stream SDK和APP SDK

10.5.5 Linux系统的驱动

10.6 异常和陷阱

10.6.1 9种异常

10.6.2 启用

10.6.3 陷阱状态寄存器

10.6.4 陷阱处理器基地址

10.6.5 陷阱处理过程

10.7 控制波阵的调试接口

10.7.1 5种操作

10.7.2 指定目标

10.7.3 发送接口

10.7.4 限制

10.8 地址监视

10.8.1 4种监视模式

10.8.2 数量限制

10.8.3 报告命中

10.8.4 寄存器接口

10.8.5 用户空间接口

10.9 单步调试支持

10.9.1 单步调试模式

10.9.2 控制方法

10.10 根据调试条件实现分支跳转的指令

10.10.1 两个条件标志

10.10.2 4条指令

10.11 代码断点

10.11.1 陷阱指令

10.11.2 在GPU调试SDK中的使用

10.12 GPU调试模型和开发套件

10.12.1 组成

10.12.2 进程内调试模型

10.12.3 面向事件的调试接口

10.13 ROCm-GDB

10.13.1 源代码

10.13.2 安装和编译

10.13.3 常用命令

10.14 本章小结

参考资料

第11章 英特尔GPU及其调试设施

11.1 演进简史

11.1.1 i740

11.1.2 集成显卡

11.1.3 G965

11.1.4 Larabee

11.1.5 GPU

11.1.6 第三轮努力

11.1.7 公开文档

11.2 GEN微架构

11.2.1 总体架构

11.2.2 片区布局

11.2.3 子片布局

11.2.4 EU

11.2.5 经典架构图

11.3 寄存器接口

11.3.1 两大类寄存器

11.3.2 显示功能的寄存器

11.4 命令流和环形缓冲区

11.4.1 命令

11.4.2 环形缓冲区

11.4.3 环形缓冲区寄存器

11.5 逻辑环上下文和执行列表

11.5.1 LRC

11.5.2 执行链表提交端口

11.5.3 理解LRC的提交和执行过程

11.6 GuC和通过GuC提交任务

11.6.1 加载固件和启动GuC

11.6.2 以MMIO方式通信

11.6.3 基于共享内存的命令传递机制

11.6.4 提交工作任务

11.7 媒体流水线

11.7.1 G965的媒体流水线

11.7.2 MFX引擎

11.7.3 状态模型

11.7.4 多种计算方式

11.8 EU指令集

11.8.1 寄存器

11.8.2 寄存器区块

11.8.3 指令语法

11.8.4 VLIW和指令级别并行

11.9 内存管理

11.9.1 GGTT

11.9.2 PPGTT

11.9.3 I915和GMMLIB

11.10 异常

11.10.1 异常类型

11.10.2 系统过程

11.11 断点支持

11.11.1 调试控制位

11.11.2 操作码匹配断点

11.11.3 IP匹配断点

11.11.4 初始断点

11.12 单步执行

11.13 GT调试器

11.13.1 架构

11.13.2 调试事件

11.13.3 符号管理

11.13.4 主要功能

11.13.5 不足

11.14 本章小结

参考资料

第12章 Mali GPU及其调试设施

12.1 概况

12.1.1 源于挪威

12.1.2 纳入ARM

12.1.3 三代微架构

12.1.4 发货最多的图形处理器

12.1.5 精悍的团队

12.1.6 封闭的技术文档

12.1.7 单元化设计

12.2 Midgard微架构

12.2.1 逻辑结构

12.2.2 三流水线着色器核心

12.2.3 VLIW指令集

12.3 Bifrost微架构

12.3.1 逻辑结构

12.3.2 执行核心

12.3.3 标量指令集和Warp

12.4 Mali图形调试器

12.4.1 双机模式

12.4.2 面向帧调试

12.5 Gator

12.5.1 Gator内核模块(gator.ko)

12.5.2 Gator文件系统(gatorfs)

12.5.3 Gator后台服务(gatord)

12.5.4 Kbase驱动中的gator支持

12.5.5 含义

12.6 Kbase驱动的调试设施

12.6.1 GPU版本报告

12.6.2 编译选项

12.6.3 DebugFS下的虚拟文件

12.6.4 SysFS下的虚拟文件

12.6.5 基于ftrace的追踪设施

12.6.6 Kbase的追踪设施

12.7 其他调试设施

12.7.1 Caiman

12.7.2 devlib

12.7.3 Mali离线编译器

12.8 缺少的调试设施

12.8.1 GPGPU调试器

12.8.2 GPU调试SDK

12.8.3 反汇编器

12.8.4 ISA文档

12.9 本章小结

参考资料

第13章 PowerVR GPU及其调试设施

13.1 概要

13.1.1 发展简史

13.1.2 两条产品线

13.1.3 基于图块延迟渲染

13.1.4 Intel GMA

13.1.5 开放性

13.2 Rogue微架构

13.2.1 总体结构

13.2.2 USC

13.2.3 ALU流水线

13.3 参考指令集

13.3.1 寄存器

13.3.2 指令组

13.3.3 指令修饰符

13.3.4 指令类型

13.3.5 标量指令

13.3.6 并行模式

13.4 软件模型和微内核

13.4.1 软件模型

13.4.2 微内核的主要功能

13.4.3 优点

13.4.4 存在的问题

13.5 断点支持

13.5.1 bpret指令

13.5.2 数据断点

13.5.3 ISP断点

13.6 离线编译和反汇编

13.6.1 离线编译

13.6.2 反汇编

13.7 PVR-GDB

13.7.1 跟踪调试

13.7.2 寄存器访问

13.7.3 其他功能

13.7.4 全局断点和局限性

13.8 本章小结

参考资料

第14章 GPU综述

14.1 比较

14.1.1 开放性

14.1.2 工具链

14.1.3 开发者文档

14.2 主要矛盾

14.2.1 专用性和通用性

14.2.2 强硬件和弱软件

14.3 发展趋势

14.3.1 从固定功能单元到通用执行引擎

14.3.2 从向量指令到标量指令

14.3.3 从指令并行到线程并行

14.4 其他GPU

14.4.1 Adreno

14.4.2 VideoCore

14.4.3 图芯GPU

14.4.4 TI TMS34010

14.5 学习资料和工具

14.5.1 文档

14.5.2 源代码

14.5.3 工具

14.6 本章小结

参考资料

第四篇 可调试性

第15章 可调试性概览

15.1 简介

15.2 观止和未雨绸缪

15.2.1 NT 3.1的故事

15.2.2 未雨绸缪

15.3 基本原则

15.3.1 最短距离原则

15.3.2 最小范围原则

15.3.3 立刻终止原则

15.3.4 可追溯原则

15.3.5 可控制原则

15.3.6 可重复原则

15.3.7 可观察原则

15.3.8 易辨识原则

15.3.9 低海森伯效应原则

15.4 不可调试代码

15.4.1 系统的异常分发函数

15.4.2 提供调试功能的系统函数

15.4.3 对调试器敏感的函数

15.4.4 反跟踪和调试的程序

15.4.5 时间敏感的代码

15.4.6 应对措施

15.5 可调试性例析

15.5.1 健康性检查和BSOD

15.5.2 可控制性

15.5.3 公开的符号文件

15.5.4 WER

15.5.5 ETW和日志

15.5.6 性能计数器

15.5.7 内置的内核调试引擎

15.5.8 手动触发崩溃

15.6 与安全、商业秘密和性能的关系

15.6.1 可调试性与安全性

15.6.2 可调试性与商业秘密

15.6.3 可调试性与性能

15.7 本章小结

参考资料

第16章 可调试性的实现

16.1 角色和职责

16.1.1 架构师

16.1.2 程序员

16.1.3 测试人员

16.1.4 产品维护和技术支持工程师

16.1.5 管理者

16.2 可调试架构

16.2.1 日志

16.2.2 输出调试信息

16.2.3 转储

16.2.4 基类

16.2.5 调试模型

16.3 通过栈回溯实现可追溯性

16.3.1 栈回溯的基本原理

16.3.2 利用DbgHelp函数库回溯栈

16.3.3 利用RTL函数回溯栈

16.4 数据的可追溯性

16.4.1 基于数据断点的方法

16.4.2 使用对象封装技术来追踪数据变化

16.5 可观察性的实现

16.5.1 状态查询

16.5.2 WMI

16.5.3 性能计数器

16.5.4 转储

16.5.5 打印或者输出调试信息

16.5.6 日志

16.6 自检和自动报告

16.6.1 BIST

16.6.2 软件自检

16.6.3 自动报告

16.7 本章小结

参考资料

累计评论(1条) 1个书友正在讨论这本书 发表评论

发表评论

发表评论,分享你的想法吧!

买过这本书的人还买过

读了这本书的人还在读

回顶部