gdb my experience

用QEMU搭建ARM Linux驱动开发环境:从虚拟到真实的嵌入式学习路径 嵌入式Linux驱动开发的核心在于理解操作系统与硬件间的通信机制,这通常涉及内核模块、设备树、中断处理等基础概念。其原理是通过硬件抽象层和驱动框架,将物理设备映射为操作系统可管理的资源,从而实现高效、稳定的硬件控制。这项技术的价值在于为物联网、智能设备等场景提供了底层支持,是连接硬件与软件生态的关键桥梁。对于初学者而言,实体开发板的成本、环境复杂性和调试难度往往成为学习障碍。QEMU模拟器通过提供可控、可观察的虚拟化环境,剥离了物理不确定性,允许开发者聚焦于驱动框架本身,使用GDB进行源码级调试,并快速迭代 阅读详情
1, 条件断点
(gdb) br EKMemory.cpp:ekmalloc  if tmpsize == 4760
或者
(gdb) br EKMemory.cpp:29  if tmpsize == 4760

(gdb) info breakpoints 
Num Type           Disp Enb Address    What
2   breakpoint     keep y   0x0041b42e in ekmalloc at src/EKLibrary/EKMemory.cpp:25  stop only if tmpsize == 4760

 

 

 

2,为停止点设定运行命令
br EKMemory.cpp:29  if tmpsize == 4760
commands
bt
continue
end

实例:
(gdb) br EKMemory.cpp:29  if tmpsize == 4760
Breakpoint 1 at 0x41b44a: file src/EKLibrary/EKMemory.cpp, line 29.
(gdb) commands
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>bt
>continue
>end
(gdb) c
Continuing.

Breakpoint 1, ekmalloc (size=4760) at src/EKLibrary/EKMemory.cpp:29
29      src/EKLibrary/EKMemory.cpp: No such file or directory.
in src/EKLibrary/EKMemory.cpp
#0  ekmalloc (size=4760) at src/EKLibrary/EKMemory.cpp:29
#1  0x0041b520 in ekioh::EKMemory::alloc (size=4760) at src/EKLibrary/EKMemory.cpp:169
#2  0x0041b5ac in operator new[] (size=4760) at src/EKLibrary/EKMemory.cpp:151
#3  0x00497f0e in ekioh::KreaTvGfxPixMap::create (width=14, height=85) at src/Platform/Motorola/KreaTvGfx/KreaTvGfxPixMap.cpp:161
#4  0x00499d14 in ekioh::KreaTvGfxPlatform::createPixMap (this=0x7be854c0, width=14, height=85, bpp=32 ' ')
at src/Platform/Motorola/KreaTvGfx/KreaTvGfxPlatform.cpp:150
#5  0x004434dc in ekioh::EKGContext::createPixMap (width=14, height=85, bpp=32 ' ', accelerated=false) at src/EKLibrary/Graphics/EKGContext.cpp:291
#6  0x2a722e1c in WebCore::ImageSource::createFrameAtIndex () from /usr/lib/libekioh_adapt_webkit525-kreatvgfx.so
#7  0x2a4a9ea0 in WebCore::BitmapImage::cacheFrame () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#8  0x2a4aa996 in WebCore::BitmapImage::frameAtIndex () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#9  0x2a4abbb0 in WebCore::BitmapImage::nativeImageForCurrentFrame () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#10 0x2a4c5062 in WebCore::Image::drawTiled () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#11 0x2a4bef74 in WebCore::GraphicsContext::drawTiledImage () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#12 0x2a54421c in WebCore::RenderBox::paintBackgroundExtended () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#13 0x2a5395cc in WebCore::RenderBox::paintBackground () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#14 0x2a5396a2 in WebCore::RenderBox::paintBackgrounds () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#15 0x2a5453da in WebCore::RenderBox::paintBoxDecorations () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#16 0x2a5305fc in WebCore::RenderBlock::paintObject () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#17 0x2a52a566 in WebCore::RenderBlock::paint () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#18 0x2a57669a in WebCore::RenderLayer::paintLayer () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#19 0x2a576cd0 in WebCore::RenderLayer::paintLayer () from /usr/lib/libekioh_webcore_webkit525-kreatvgfx.so
#20 0x2ce1a510 in ?? ()
#21 0x2ce1a510 in ?? ()
Previous frame identical to this frame (corrupt stack?)


3,调试运行中程序
gdb -p PID
(gdb) breakpoints EKMemory.cpp:29  if tmpsize == 4760
(gdb) c

 

 

4 gdb 查看core dump ;

 

4.1. 前言:
有的程序可以通过编译, 但在运行时会出现Segment fault(段错误). 这通常都是指针错误引起的.
但这不像编译错误一样会提示到文件->行, 而是没有任何信息, 使得我们的调试变得困难起来.

4.2. gdb:
有一种办法是, 我们用gdb的step, 一步一步寻找.
这放在短小的代码中是可行的, 但要让你step一个上万行的代码, 我想你会从此厌恶程序员这个名字, 而把他叫做调试员.
我们还有更好的办法, 这就是core file.

4.3. ulimit:
如果想让系统在信号中断造成的错误时产生core文件, 我们需要在shell中按如下设置:
#设置core大小为无限
ulimit -c unlimited
#设置文件大小为无限
ulimit unlimited

这些需要有root权限, 在ubuntu下每次重新打开中断都需要重新输入上面的第一条命令, 来设置core大小为无限.

4.4. 用gdb查看core文件:
下面我们可以在发生运行时信号引起的错误时发生core dump了.
发生core dump之后, 用gdb进行查看core文件的内容, 以定位文件中引发core dump的行.
gdb [exec file] [core file]
如:
gdb ./test test.core
在进入gdb后, 用bt命令查看backtrace以检查发生程序运行到哪里, 来定位core dump的文件->行.

4.5. 用gdb实时观察某进程crash信息
启动进程
gdb -p PID
c
运行进程至crash
gdb会显示 crash信息
bt

 

 

 

5, gdb used on kreatv:

his is a tip about how to use gdb to check the crash bug:

5.1  . add "kreatv-tool-gdb" to bootimage
5.2. use kernel+nfs to boot up the box.
5.2.1 copy the execute file and .so lib into rootdisk's related position. 
[leo@leo dlnamediacontroller]$ sudo cp st40/dlnamediacontroller /opt/nfs/rootdisk/usr/bin/dlnamediacontroller
[leo@leo dlnamediacontroller]$ pwd
/mnt/sda5/mot_develop/BRASSICA/platform/dlnamediacontroller


5.3. update the rootdisk/usr/bin/start_platform.sh to enable the core dump.
export COREDUMP_ENABLED=yes


5.4. when crash happens, core dump files are stored in the box's / directory. For example core.1167 which means the core dump file is created by the process pid 1167 5. telnet to the box and use gdb to check the core dump. For example, if the streamer crash and the pid is 574, run gdb like this:

The following can use box or PC.  It is better run in box which need add "kreatv-tool-gdb" to bootimage.
# gdb /usr/bin/streamer core.574


5.6. If you are luck, you can see  the streamercrashat which function and which line.

5.7. Most of time, you are not luck, you only can see some  information like this:
#0  0x298ae0a4 in ?? ()
(gdb)bt
#0  0x298ae0a4 in ?? ()
#1  0x298af5a0 in ?? ()
This is because most of our binary and library are strippedbefore copying the the rootdisk.  
Replacing the binary or library in the rootdisk with the original one built from branch and test again! Then you can see the detail function name.

It is proved very useful to fix some kinds of crash bug.





How can we crash process or box?
assert(1==0);  will trige it.
int a = 1/0;  will trige it.
char *abcd;
memcpy(abcd, "12345678",8); will trige it.



How to analyze core dump
• Run gdb in box
• or Run arm-kreatel-linux-gnu-gdb in PC
• Command example
   – #xxx_gdb /usr/bin/streamer -c /tmp/core.dump
   – #bt


Readme:
a, kreatv-tool-gdb  only decide whether you can telnet box,and gdb on box.

 

example: 

 /# gdb /usr/applications/ekioh/ekioh  core.526
GNU gdb 6.5-ST-1.0-ST40 [build Jul  2 2009]
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "sh4-motorola-linux-gnu"...(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /usr/lib/libVirtualDisplay.so...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libVirtualDisplay.so


Loaded symbols for usr/browser/plugins/libmotorolatoi.so
Got object file from memory but can't read symbols: File format not recognized.

Core was generated by `/usr/applications/ekioh/ekioh --cache 0 --url http://192.168.5.215'.
Program terminated with signal 7, Bus error.
#0  0x29f3224c in KJS::Bindings::Instance::setValueOfField () from /usr/lib/libjavascriptcore.so


(gdb) bt
#0  0x29f3224c in KJS::Bindings::Instance::setValueOfField () from /usr/lib/libjavascriptcore.so
#1  0x29919512 in ekioh::GTKSocketCollection::callback (source=<value optimized out>, condition=2076097000, data=0x443b50)
    at src/Platform/GTK/GTKSocketCollection.cpp:255
#2  0x2a5ebbf2 in g_io_add_watch () from /usr/lib/libglib-1.2.so.0
#3  0x2a5ecdb2 in g_main_add_poll () from /usr/lib/libglib-1.2.so.0
#4  0x2a60875c in ?? () from /usr/lib/libglib-1.2.so.0
#5  0x2a60875c in ?? () from /usr/lib/libglib-1.2.so.0
Previous frame identical to this frame (corrupt stack?)

(gdb) q
/ # exit
Connection closed by foreign host.
[root@localhost infocast]#

 

6, 如何查看?  的内存地址空间???

llama.cpp与Ollama原理实战:GGUF量化、CUDA加速与OpenAI兼容部署 大模型本地推理框架的核心在于运行时轻量化与硬件无关的模型封装。llama.cpp作为纯C/C++实现的模型运行时环境,依托GGUF格式统一管理权重、tokenizer和量化元数据,实现零Python依赖的跨平台部署;其量化机制(如Q4_K_M)并非简单压缩,而是在可控误差内重分布计算负载,显著提升CPU/GPU推理效率。Ollama则构建了类操作系统的模型分发体系,通过语义化索引、模板自动协商与Content-Addressed存储,屏蔽底层复杂性,并提供OpenAI兼容API,使开发者可快速集成至现有工程 阅读详情

相关推荐

ANSA二次开发在线帮助:ANSA和μETA API文档

  为了方便大家学习ANSA二次开发,我将ANSA和μETA二次开发的官方文档整合到了我的个人网站CAECoder中,大家点击ANSA和μETA API官方帮助文档进行访问即可查看。   本站也将开展对ANSA和μETA API文档的翻译工作,请大家持续关注! ANSA和μETA API文档   ANSA和μETA脚本接口是一个应用程序编程接口(API),允许开发人员访问ANSA和μETA核心功能和数据。   ANSA和μETAAPI是Python编程语言的扩展。 Python Python简.

CAECoder 4320

gdb工具的使用

Linux和windows同为操作系统,前者是命令行形式,后者使用图形化界面形式,两者虽然形式不同但操作确实对应的。Windows下的调试方法大家应该都很熟悉了,今天就来介绍一下gdb,作为Linux下的调试工具,它的功能也很强大。在Windows下调试,以VS为例,F5是调试运行,如果碰到断点就停下来,没断点就运行到结尾。如果既不想在函数内逐语句调试,也不想跳到下一个断点,只想跑完当前这个函数,用。进入循环后,p +变量就可以打印该变量的值,但是下一次循环则不会继续显示。

SAKURAjinx的博客 911

强化学习之课程学习法

课程学习是一种有计划的学习方法,模拟人类学习的过程。它通过设置逐步增加难度的任务序列,让学习系统从简单的任务开始,逐渐过渡到复杂任务。这一方法可以显著提高训练效率,避免智能体一开始就面临过于复杂的任务,从而导致学习过程困难。逐步难度增加:从简单的任务开始,逐步增加任务的难度,直到智能体能够解决最复杂的任务。动态调整:根据智能体的学习进展,动态调整任务的难度,保证学习的过程始终处于一个适当的挑战性范围。

m0_64087341的博客 2694

osgviewerMFC实例中内存泄漏严重问题

MFC加入OSG视图 报错严重

MSDN8341的专栏 1392

如何对正射影像DOM(卫星影像、无人机航拍影像)进行拼接、合并以及去黑边(附 Global Mapper Pro 24.0 安装包(中文注册版))

为什么要对正射影像DOM进行拼接?影像去黑边、影像拼接的操作和步骤。

从地图看世界的专栏 4298

【重识云原生】第四章云网络4.9.5.1节下一代智能网卡——DPU综述

随着数据中心的高速发展,通信能力和计算能力成为数据中心基础设施的相辅相成的两个重要发展方向。若数据中心仅关注计算能力的提升,通信基础设施的提升跟不上,那么数据中心的整体系统性能依然受限,无法发挥出真正的潜力。DPU的提出背景就是应对这些数据量和复杂性的指数级增长。未来,需要将计算移至接近数据的位置,这是目前业界所公认的以数据为中心的体系结构下的创新。综上,DPU对数据中心来说,是通过更明细的分工来实现效率的提升、实现总体系统的成本最优化。...

junbaozi的专栏 1724

Memory内存种类大全与简介

(原文:https://tech.hqew.com/news_1538989) 根据组成元件的不同,RAM内存又分为以下十八种:   01.DRAM(Dynamic RAM,动态随机存取存储器):   这是最普通的RAM,一个电子管与一个电容器组成一个位存储单元,DRAM将每个内存位作为一个电荷保存在位存储单元中,用电容的充放电来做储存动作,但因电容本身有漏电问题,因此必须每几微秒就要刷新一...

youshengchao的博客 1万+

【虚幻引擎UE】UE5 阴影异常与优化

【虚幻引擎UE】UE5 阴影异常与优化解决方案合集

灵境引路人 3万+

内存(Memory)

      内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。内存(Memory)也被称为内存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行。 ...

weixin_38452632的博客 7444

人工智能技术基础系列之:迁移学习

作者:禅与计算机程序设计艺术 1.背景介绍 随着深度学习和神经网络的快速发展,越来越多的应用场景需要处理大量的数据和复杂的任务。然而,由于计算资源、存储空间等条件的限制,传统的人工智能方法往往不能满足实际需求。因此,为了提高效率和降低成本,研究人员提出了迁移学习的概念。本篇文章将详细介绍迁移学习的基

AI天才研究院 695

EndNote X9 快速上手教程(毕业论文参考文献管理器)

EndNote X9 快速上手教程一、EndNote X9安装1.安装2 安装之后重要步骤二、第一次打开 EndNote三、参考文献引用1. 导入知网文献2. 参考文献引用四、常见问题1. 引用文献中出现%J的问题2 参考文献中出现et.al1 在文章中引用的编号的地方出现2 在参看文献列表里出现 一、EndNote X9安装 1.安装 打开文件夹 安装前,一定要读 #Readme.txt 文件 一定要把License.dat和ENX9Inst.msi放在同一文件夹,安装的时候会自动激活。 我的安装路

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 2万+

mysql load data local infile_MySQL代码学习第二——用gdb简单跟踪

上文已经编译安装了一份MySQL8.0.15,也初始化完成了。古雷:MySQL代码学习第一——MySQL8.0.15源码编译​zhuanlan.zhihu.com可以开始走走看看了。因为编译安装了GCC的关系,还是少不了这个export LD_LIBRARY_PATH=/usr/local/gcc-5.5.0/lib64[root@localhost ~这就成功进入gdb了,激动地用 l 命令看一...

weixin_39631689的博客 391

【DDR5 PCB走线SI/PI仿真调试】详细全攻略

问题场景发现症状优化措施过孔Stub效应TDR波形尖峰,信号反射严重使用盲孔,背钻减少Stub,降低Via数量串扰过大眼图闭合,误码率增加增加走线间距,插入地线隔离,减少平行长度电源阻抗过高PDN谐振导致纹波大多频率去耦,靠近电源引脚布置多档电容,合理分层信号时序失配优化走线长度匹配,避免信号走线跨层跳变DDR5设计不仅是硬件的挑战,更是仿真能力的考验。掌握SI/PI仿真,理解信号背后的物理本质,才能真正把握高速接口的“灵魂”!

weixin_43199439的博客 987

Network Simulator 2 for Wireless : My Experience

Introduction Ns-2 is a widely used tool to simulate the behavior of wired and wireless networks. Useful general information can be found at  Official ns-2 website (http://www.isi.edu/nsnam/ns/ )

norbert.jiang的专栏 916

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Hacker's Experience

http://72.14.235.104/search?q=cache:ys6DSYc0GcIJ:www.12000.org/my_notes/system_calls_in_linux/system_call_in_linux...

cjcap08822的专栏 326

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C++单元测试中getrandom异常:Linux内核兼容性问题深度解析与解决方案

在C++开发中,随机数生成是基础且关键的功能,尤其在单元测试、密码学和安全敏感场景中。其原理通常依赖于系统提供的熵源,如Linux内核的随机数生成器。现代C++的std::random_device等设施在底层会调用系统调用(如getrandom)或读取设备文件(如/dev/urandom)来获取高质量随机种子,这是确保随机性质量和程序安全性的技术基石。当底层系统调用因环境不兼容(如旧版本Linux内核)而失败时,就会引发运行时异常,直接影响测试流程和CI/CD流水线的稳定性。本文聚焦于解决因getrand

weixin_30732487的博客 452

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Windows 安装 WSL 提示:WslRegisterDistribution failed with Error: 0x8007019e /wsl --list --online 无法解析服务器

……

u013669912的博客 2万+

Open3D闪退问题分析与解决方案

在3D数据处理和可视化领域,内存管理和图形渲染是核心技术挑战。Open3D作为开源3D处理库,其闪退问题常源于内存溢出或显卡驱动不兼容。理解点云数据处理原理和OpenGL渲染机制,开发者能有效预防程序崩溃。通过内存映射、数据分块等技术优化资源使用,结合驱动更新和环境隔离等方法,可显著提升大型3D项目稳定性。本文针对Open3D闪退提供系统解决方案,涵盖从基础调试到高级性能优化的全流程实践。

weixin_34288121的博客 383

边用llama.cpp边学C++:Windows 11下真实工程驱动的入门路径

C++是一门强工程导向的语言,其核心价值在于对内存、硬件和系统资源的直接掌控。理解std::vector的RAII语义、std::thread的生命周期管理、CUDA与CPU协同的构建逻辑,远比孤立记忆语法更重要。llama.cpp作为轻量级但工业级的大模型推理引擎,天然融合了现代C++关键特性(如constexpr、模板元编程、跨平台条件编译)与底层实践(mmap内存映射、AVX指令对齐、OpenMP并发优化),成为连接语法知识与真实系统行为的理想桥梁。尤其在Windows 11 + CUDA环境下,从编

weixin_33700350的博客 407

Godot 4.2.1控制台闪退:五大根源与系统性排查修复指南

在软件开发和游戏引擎部署中,运行时环境依赖与图形API兼容性是保障应用稳定启动的基础。以C++编写的应用通常依赖特定版本的VC++运行时库,缺失或版本不匹配会导致进程初始化失败。同时,现代渲染引擎如Godot默认采用Vulkan API,其对显卡驱动的版本和兼容性有严格要求,驱动过旧或损坏会直接导致渲染后端初始化崩溃。这些底层原理决定了应用能否在目标系统上成功运行,其技术价值在于为无头渲染、自动化构建和CI/CD流水线提供可靠的无界面执行环境。本文聚焦于Godot 4.2.1控制台版本启动即闪退的典型问题,

迷彩风情 321

Memory内存操作函数

一、malloc/calloc 名称: malloc/calloc 功能: 动态内存分配函数 头文件: #include<memory.h> 函数原形: void*malloc(size_tsize); void...

海纳百川,有容乃大。 4416

C++11 FAQ中文版

C++11 FAQ中文版 http://www.chenlq.net/cpp11-faq-chs http://www.stroustrup.com/C++11FAQ.html Morgan Stanley | Columbia University | Texas A&M University home | 

探秘 4736

dmalloc的使用

dmalloc到/usr/local/bin/目录下。  (6) 设置环境变量: 对于 Bash, ksh, and zsh (http://www.zsh.org/), 在 `.bashrc', `.profile', or `.zshrc' 文件中加入一行 ( -b 参数表示针对Bash的输出): function dmalloc { eval `/usr/local/bin/dm

探秘 4384

十六进制 字符打印

printf打印字符的十六进制格式,需要unsigned char转换一下 printf("[%02x]\n",(unsigned char)str[i]); gdb打印16进制字符:p/x str[0] unsigned char **specificInfoH;         for(UINT32 i=0; isize - bytesSkipped; i+

探秘 3436

C中如何调用C++函数

1,在C中如何调用C++函数将函数用extern "C"声明; 将 C++ 函数声明为``extern "C"''(在你的 C++ 代码里做这个声明),然后调用它(在你的 C 或者 C++ 代码里调用)。例如: // C++ code: extern "C" void f(int); void f(int i) { // ... } 然后,你可以这样使用 f(): /* C

探秘 2549

Makefile,如何传递宏定义DEBUG

1, gcc中使用宏的例子: 在程序中,通过有这样的代码段:    #ifdef   DEBUG    printf("Debug   is   define!\n");    #endif    printf("Hello   World!\n");    希望在编译时,传递DEBUG定义,实现Debug版本和Release版本的区别。    gcc   -DDEBUG  

探秘 2278
上一篇: Linux的时间函数
下一篇: Valgrind 内存检测工具
bamboolsu
博客等级 码龄22年 200粉丝 394原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值