当前位置: 首页 > news >正文

Linux:strace 简介

文章目录

  • 1. 前言
  • 2. 什么是 strace ?
  • 3. 使用 strace
    • 3.1 追踪指定进程
      • 3.1.1 通过程序名追踪进程
      • 3.1.2 通过 进程 ID (PID) 追踪程序
      • 3.1.3 追踪 子进程 或 线程
    • 3.2 系统调用情况统计
    • 3.3 追踪过滤
      • 3.3.1 追踪指定的系统调用集合
      • 3.3.2 追踪对指定文件句柄集合操作的系统调用
      • 3.3.3 追踪访问指定路径的系统调用
      • 3.3.4 追踪返回成功的系统调用
      • 3.3.5 追踪返回错误码的系统调用
      • 3.3.6 指定系统调用类别
    • 3.4 输出控制
      • 3.4.1 输出时间戳
      • 3.4.2 将追踪结果写入文件
    • 3.5 其它选项
  • 4. 交叉编译 strace
  • 5. 参考资料

1. 前言

限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。

2. 什么是 strace ?

straceLinux 下一款诊断、调试、追踪工具,它可以用来监控和获取内核的系统调用、信号投递、进程状态变更等信息。其基本实现机制是通过 ptrace() 系统调用,来获取内核相关信息。对 strace 实现原理感兴趣的读者,可直接阅读 strace 源码,或参考博文 Linux:系统调用追踪原理简析 。

3. 使用 strace

3.1 追踪指定进程

3.1.1 通过程序名追踪进程

在程序启动时,可通过 strace 跟踪程序运行期间的所有系统调用。如:

# strace ls
execve("/bin/ls", ["ls"], 0xbeb73e50 /* 12 vars */) = 0
brk(NULL)                               = 0xc3000
uname({sysname="Linux", nodename="(none)", ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6f0e000
...
stat64(".", {st_mode=S_IFDIR|0755, st_size=232, ...}) = 0
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3
getdents64(3, 0xc30b0 /* 3 entries */, 32768) = 80
lstat64("./tcp_server", {st_mode=S_IFREG|0755, st_size=11192, ...}) = 0
getdents64(3, 0xc30b0 /* 0 entries */, 32768) = 0
close(3) 
...
exit_group(0)                           = ?
+++ exited with 0 +++

上面的输出,每一行显示一个系统调用,包含系统调用名、调用参数、以及返回值(= 后的内容),譬如输出:

openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3

表示调用了 open() ,打开的是当前目录 "." ,传递的 flags 参数为 O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY,返回值为 3

3.1.2 通过 进程 ID (PID) 追踪程序

首先找到目标进程的 PID:

# ps -ef | grep -v grep | grep InfiniteDsp160 root     ./InfiniteDsp

然后进行追踪:

# strace -p 160
strace: Process 160 attached
read(27, "\1\0\0\0", 4)                 = 4
[......]

3.1.3 追踪 子进程 或 线程

对于调用 fork()clone() 等系列接口的程序,在 3.1.1,3.1.2 基础上,需再加上 -f--follow-forks 命令行参数来进程追踪:

strace -f <program>
strace -fp <PID>

如有一个 PID 为 2622 的多线程程序,我们用 strace 来追踪它:

# strace -fp 2622
strace: Process 2622 attached with 4 threads
[pid  2627] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2626] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2625] restart_syscall(<... resuming interrupted restart_syscall ...> <unfinished ...>
[pid  2622] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2626] <... restart_syscall resumed> ) = 0

从输出看到,PID 为 2622 的进程有 4 个线程,同时输出每行开头都带上了线程的 PID ,这样就能知道每个系统调用是由哪个线程发起的。

3.2 系统调用情况统计

通过 -c-C 命令行参数,统计系统调用消耗的总时间、调用总次数、每次消耗的平均时间、出错总次数等信息,并在结束追踪时输出这些信息。-c-C 的差别在于:-c 不会在追踪期间输出系统调用情况,而 -C 则相反。看一个简单的例子:

# strace -C -fp 2622
strace: Process 2622 attached with 4 threads
[pid  2626] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2627] restart_syscall(<... resuming interrupted restart_syscall ...> <unfinished ...>
[pid  2625] restart_syscall(<... resuming interrupted restart_syscall ...> <unfinished ...>
[pid  2622] restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
[pid  2626] <... restart_syscall resumed> ) = 0
[......]
^Cstrace: Process 2622 detached<detached ...>
strace: Process 2625 detached
strace: Process 2626 detached
strace: Process 2627 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------84.95    0.000948         474         2           restart_syscall8.42    0.000094          47         2         2 inotify_add_watch6.63    0.000074          25         3         2 recvmsg
------ ----------- ----------- --------- --------- ----------------
100.00    0.001116                     7         4 total

3.3 追踪过滤

3.3.1 追踪指定的系统调用集合

有时候并不想追踪程序所有的系统调用,通过下列选项

-e trace=syscall_set
-e t=syscall_set
--trace=syscall_set

指定想追踪不想追踪的系统调用集合。如只想追踪程序的 open() 调用:

# strace -e t=open /bin/ls
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/proc/filesystems", O_RDONLY)     = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
[......]
+++ exited with 0 +++

strace 只输出程序运行过程中所有 open() 调用。如果想追踪多个系统调用,可以用 , 分隔,如:

# strace -e t=open,read /bin/ls
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260Z\0\0\0\0\0\0"..., 832) = 832
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\t\2\0\0\0\0\0"..., 832) = 832
open("/lib/x86_64-linux-gnu/libpcre.so.3", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\25\0\0\0\0\0\0"..., 832) = 832
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\r\0\0\0\0\0\0"..., 832) = 832
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260`\0\0\0\0\0\0"..., 832) = 832
open("/proc/filesystems", O_RDONLY)     = 3
read(3, "nodev\tsysfs\nnodev\trootfs\nnodev\tr"..., 1024) = 429
read(3, "", 1024)                       = 0
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open(".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
[......]
+++ exited with 0 +++

3.3.2 追踪对指定文件句柄集合操作的系统调用

通过下列选项:

-e trace-fd=set
-e trace-fds=set
-e fd=set
-e fds=set

追踪对指定文件句柄集合操作的系统调用。如追踪所有对文件句柄 3 的操作:

# strace -e fd=3 /bin/ls
read(3, "\177ELF\1\1\1\3\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\235h\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0777, st_size=898752, ...}) = 0
mmap2(NULL, 968040, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb6e01000
mmap2(0xb6ee8000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xd7000) = 0xb6ee8000
close(3)                                = 0
getdents64(3, 0xc30b0 /* 14 entries */, 32768) = 456
getdents64(3, 0xc30b0 /* 0 entries */, 32768) = 0
close(3)                                = 0
[......]
+++ exited with 0 +++

3.3.3 追踪访问指定路径的系统调用

通过下列选项:

-P path
--trace-path=path

追踪指定访问目录的系统调用。

# strace --trace-path=/var /bin/ls /var
stat64("/var", {st_mode=S_IFDIR|0777, st_size=672, ...}) = 0
openat(AT_FDCWD, "/var", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3
getdents64(3, 0xc30b0 /* 10 entries */, 32768) = 256
getdents64(3, 0xc30b0 /* 0 entries */, 32768) = 0
close(3)                                = 0
[......]
+++ exited with 0 +++

3.3.4 追踪返回成功的系统调用

通过下列选项:

-z
--successful-only

只追踪返回成功的系统调用。

3.3.5 追踪返回错误码的系统调用

通过下列选项:

-Z
--failed-only

只追踪返回错误码的系统调用。

3.3.6 指定系统调用类别

从前面知道,下列选项

-e trace=syscall_set
-e t=syscall_set
--trace=syscall_set

可以指定要追踪的系统调用集合。前面已经示范了通过具体的名字来指定集合,这里介绍通过类别指定系统调用集合的方式,即 syscall_set 还可以通过如下方式指定:

/regex : 正则表达式
%file, file: 追踪文件操作相关的系统调用(open,close,access,...)
%process, process: 追踪进程操作相关的系统调用(exec,...)
%net, %network, network: 追踪网络操作相关的系统调用(recv,...)
......

3.4 输出控制

3.4.1 输出时间戳

选项

-r 
--relative-timestamps[=precision]

输出相对时间(相对于程序启动时间):

# strace -r /bin/ls0.000000 execve("/bin/ls", ["/bin/ls"], [/* 26 vars */]) = 00.000589 brk(NULL)                 = 0x188c0000.000323 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)0.000285 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)0.000209 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 30.000335 fstat(3, {st_mode=S_IFREG|0644, st_size=100481, ...}) = 00.000566 mmap(NULL, 100481, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9a94f300000.000304 close(3)                  = 0[......]0.000096 exit_group(0)             = ?0.000101 +++ exited with 0 +++

选项

-t
--absolute-timestamps

输出绝对时间:

# strace -t /bin/ls
11:18:35 execve("/bin/ls", ["/bin/ls"], [/* 26 vars */]) = 0
11:18:35 brk(NULL)                      = 0x14f0000
11:18:35 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
11:18:35 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
[......]

选项

-T
--syscall-times[=precision]

输出每个系统调用消耗的时间:

# strace -T /bin/ls
execve("/bin/ls", ["/bin/ls"], [/* 26 vars */]) = 0 <0.000381>
brk(NULL)                               = 0x1701000 <0.000126>
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory) <0.000135>
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory) <0.000094>
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 <0.000084>
[......]

3.4.2 将追踪结果写入文件

选项

-o filename
--output=filename

将追踪结果写入文件。

3.5 其它选项

strace 的更多使用方法可参考其手册 https://www.man7.org/linux/man-pages/man1/strace.1.html 。

4. 交叉编译 strace

先获取 strace 源码(当前版本为 6.6):

git clone https://gitlab.com/strace/strace.git

交叉编译 strace 源码(假定目标平台为 ARM32,交叉编译器为 arm-linux-gnueabihf-gcc):

./bootstrap
CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld RANLIB=arm-linux-gnueabihf-ranlib \
./configure --prefix=$(pwd)/out --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf
make && make install

将在 out 目录下生成 strace 程序:

$ tree out
out
├── bin
│   ├── strace
│   └── strace-log-merge
└── share└── man└── man1├── strace.1└── strace-log-merge.1

5. 参考资料

[1] https://strace.io/
[2] https://www.man7.org/linux/man-pages/man1/strace.1.html

相关文章:

Linux:strace 简介

文章目录 1. 前言2. 什么是 strace ?3. 使用 strace3.1 追踪指定进程3.1.1 通过程序名追踪进程3.1.2 通过 进程 ID (PID) 追踪程序3.1.3 追踪 子进程 或 线程 3.2 系统调用情况统计3.3 追踪过滤3.3.1 追踪指定的系统调用集合3.3.2 追踪对指定文件句柄集合操作的系统调用3.3.3 …...

【深度学习】神经网络训练过程中不收敛或者训练失败的原因

在面对模型不收敛的时候&#xff0c;首先要保证训练的次数够多。在训练过程中&#xff0c;loss并不是一直在下降&#xff0c;准确率一直在提升的&#xff0c;会有一些震荡存在。只要总体趋势是在收敛就行。若训练次数够多&#xff08;一般上千次&#xff0c;上万次&#xff0c;…...

el-table修改表格每行的高度包含表头

需求&#xff1a; 需要修改el-table表格每行的高度为54px&#xff0c;并且包含表头。 .el-table {tr {height: 54px;td {padding: 0;}th {padding: 0;}} }如果样式没有生效&#xff0c;可能.el-table需要加上样式穿透...

常用数据存储格式介绍:Excel、CSV、JSON、XML

在现代数字时代&#xff0c;数据经过提炼后可以推动创新、简化运营并支持决策流程。然而&#xff0c;在提取数据之后&#xff0c;并将其加载到数据库或数据仓库之前&#xff0c;需要将数据转化为可用的数据存储格式。本文将介绍开发者常用的4种数据存储格式&#xff0c;包括 Ex…...

kafka 集群 KRaft 模式搭建

Apache Kafka是一个开源分布式事件流平台&#xff0c;被数千家公司用于高性能数据管道、流分析、数据集成和关键任务应用程序 Kafka 官网&#xff1a;https://kafka.apache.org/ Kafka 在2.8版本之后&#xff0c;移除了对Zookeeper的依赖&#xff0c;将依赖于ZooKeeper的控制器…...

如何进行有效的移动应用测试?

1、识别关键功能: 对于移动应用测试&#xff0c;首先要了解应用的需求和功能规格&#xff0c;确定哪些功能是最关键的。 关键功能通常是用户最常用的功能&#xff0c;对应用的成功和用户体验至关重要。 2、设定测试目标和用例: 针对每个关键功能&#xff0c;设置具体的测试目…...

飞翔的鸟小游戏

第一步是创建项目 项目名自拟 第二步创建个包名 来规范class 再创建一个包 来存储照片 如下 package game; import java.awt.*; import javax.swing.*; import javax.imageio.ImageIO;public class Bird {Image image;int x,y;int width,height;int size;double g;double t;…...

吴恩达《机器学习》10-1-10-3:决定下一步做什么、评估一个假设、模型选择和交叉验证集

一、决定下一步做什么 在机器学习的学习过程中&#xff0c;我们已经接触了许多不同的学习算法&#xff0c;逐渐深入了解了先进的机器学习技术。然而&#xff0c;即使在了解了这些算法的情况下&#xff0c;仍然存在一些差距&#xff0c;有些人能够高效而有力地运用这些算法&…...

大数据-之LibrA数据库系统告警处理(ALM-37000 MPPDBServer数据目录或Redo目录缺失)

告警解释 当出现如下情况时&#xff0c;产生该告警&#xff1a; 数据实例数据目录被删除。数据实例Redo目录&#xff08;pg_xlog&#xff09;被删除。 告警属性 告警ID 告警级别 可自动清除 37000 严重 是 告警参数 参数名称 参数含义 ServiceName 产生告警的服务…...

华为eNSP使用教程(Enterprise Network Simulation Platform,企业网络仿真平台)

文章目录 华为eNSP使用教程详解引言eNSP界面快速入门启动与初始设置主界面组成创建和管理项目 构建网络拓扑添加和连接设备配置设备参数示例&#xff1a;配置设备接口IP 保存配置 仿真网络功能启动与测试示例&#xff1a;测试网络连通性 使用调试工具 疑难技术点解析路由协议配…...

19.Spring如何处理线程并发问题?

Spring如何处理线程并发问题? 在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。 ThreadLocal和线程同步机制都是为了解决多…...

Python办公神器:教你如何快速分拆、删页、合并PDF文件

哈喽大家好&#xff0c;我是了不起&#xff0c;今天教你如何用Python快速分拆、删页、合并PDF文件 介绍 有时我们可能需要对PDF文件进行一些处理&#xff0c;例如分拆、删页、合并等。这些操作在一些专业的PDF软件中可能比较容易实现&#xff0c;但是如果我们想要用Python来自…...

Android aidl的简单使用

一.服务端 1.创建aidl文件&#xff0c;然后记得build下生成java文件 package com.example.aidlservice31;// Declare any non-default types here with import statementsinterface IMyAidlServer {// 接收一个字符串参数void setData(String value);// 返回一个字符串String …...

双十一备战与复盘

如何组织备战 重要节点 从大促启动会开始后我就开始计划我们本次备战的整体节奏。 挑战在哪 以上内容介绍了CDP平台有多么重要&#xff0c;那么画像系统备战的核心挑战在“如何保障在大流量高并发情况下系统稳定提供高性能服务”&#xff0c;主要表现在&#xff1a;稳定性、…...

ONNX实践系列-修改yolov5-seg的proto分支输出shape

一、目标 本文主要介绍要将原始yolov5分割的输出掩膜从[b,c,h,.w]修改为[b, h, w, c] 原来的: 目标的: 代码如下: Descripttion: version: @Company: WT-XM Author: yang jinyi Date: 2023-09-08 11:26:28 LastEditors: yang jinyi LastEditTime: 2023-09-08 11:48:01 …...

VMware与Linux安装

VM与Linux安装 1、安装VMware ​ 这里安装Vm主要是为了安装Linux系统&#xff0c;除了相对云服务器&#xff0c;比较大众化的操作&#xff0c;当然更多的是熟悉Linux操作 1、Windows安装 ​ (1) 下载链接&#xff0c;目前版本上下载VM15的版本即可https://www.vmware.com/p…...

服务器连接github

https://zhuanlan.zhihu.com/p/543490354 比着这个一步步做就行。 https://blog.l0v0.com/posts/94ffdbdf.html 上传文件可以看这个 注意&#xff1a; 密钥ssh-keygen设置好之后&#xff0c;以后就不用每次输入账号密码才能访问了。 otherwise&#xff0c;每次要输入账号密码。…...

自动驾驶中的LFM(LED 闪烁缓解)问题

自动驾驶中的LFM Reference: 自动驾驶系统如何跨越LFM这道坎&#xff1f; 从路灯、交通灯&#xff0c;到车载照明&#xff0c;低功耗、长寿命、高可靠的 LED 正在快速取代传统照明方式。但 LED 在道路上的普遍使用&#xff0c;却带来“LED闪烁”现象。“LED闪烁”是由 LED 驱…...

ArkTS-页面和自定义组件生命周期

页面生命周期&#xff1a;被Entry装饰的组件生命周期 onPageShow&#xff1a;页面每次显示时触发一次&#xff0c;包括路由过程、应用进入前台等场景onPageHide&#xff1a;页面每次隐藏时触发一次&#xff0c;包括路由过程、应用进入前后台等场景onBackPress&#xff1a;当用户…...

ELK: logstash gork filter 多个模式(pattern)匹配规则语法和多行日志匹配设置

项目里用logstash分析日志&#xff0c;由于有多种模式&#xff08;pattern&#xff09;需要匹配&#xff0c;网上搜了很多示例&#xff0c;发现这些都是老的写法&#xff0c;都会报错&#xff0c;后来查阅了官方文档&#xff0c;才发现&#xff0c;新版本只支持新语法。 错误的…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...