Linux第九节课 - git / gdb

注意点:

  • 缓冲区中的内容被保存起来刷新不出来在Windows看不出来,只有在Linux系统下可以看出来!
  • extren关键字声明函数的时候可带可不带,因为在头文件进行一定是进行函数的声明,但是变量的声明一定要带上extern!

进度条的思路:

从左到右,第一次显示1个字符,第二次显示2个字符,第三次显示3个字符.......

每次显示多一个字符,且将前面的字符给覆盖掉!

注意点:

  • 使用usleep函数(头文件依然为#include<unistd.h>)

休眠时间为微秒!   1s = 1000毫秒 = 1000*1000微秒!

  • 右括号不动,左边最终#移动至右括号:空字符不占位置,有效输出的#一共有100个 --- >>> [%-100s]
  • 此时我们还想输入百分比%:在[%-100s]右边加上[%d] --- cnt即可 --- 但是此时只显示数字,没有对应的百分比!
  • 用两个%来显示百分号![%d%%];或者\%(转义字符)也可以打印%,但是不推荐

如何实现一个加载符号(旋转光标)?

方法(原理):第一次输出一个 | ,第二次覆盖式的写入一个 / ,第三次覆盖式的写入 — ,第四次再覆盖式的写入 \ ,然后再写入 — !

注意点:\(反斜杠是一个特殊的字符),因此通过\\解除注释表示一个\\!

如果我们想写成最后一个符号是>的形式,可以参考下列代码:

   15   while(cnt <= 100)                           
   16   {                                           
   17     printf("[%-100s][%d%%][%c]\r",bar,cnt,lable[cnt % len]);  // 没有\n,就没有立即刷新,因为显示器模式是行刷新
   18     fflush(stdout);                           
   19     bar[cnt++] = Str_style;                   
   20     bar[cnt] = '>';     // 在这次循环中,前cnt行打印的是Str_style,然后cnt+1,在cnt+1行打印'>'                                
E> 21     usleep(100000);                        
   22   } 

但是该代码有个问题:我们一共定义102个字符(循环从0~100执行了101次,显示101个数字,\0为第102个)

当cnt = 100时,此时循环内在cnt = 101的位置上将其改为'>',但是101上面应该放\0,因为我们应该加上条件判断!

如果我们不希望程序结束后,#留在最后:将cnt = 100的情况删去!

此时进度条进度已经差不多了,我们可以将程序优化一下:将数字改成宏,函数自定义传入参数等

最后显示进度条代码对应的源文件和头文件:

头文件:processBar.h

#pragma once

#include<stdio.h>
#define Str_style '='  // 将字符定义为#
#define NUM 102 // 循环共101次,再加上\n一共102
#define BODY '='
#define RIGHT '>'
#define TOP 100    // 循环次数

extern void processbar(int rate);

源文件:processBar.c

#include<stdio.h>
#include"processBar.h"
#include<string.h>

const char *lable = "|/-\\";
// v2版本:进度条如何被调用的?
char bar[NUM];
void processbar(int rate)
{
  if(rate < 0 || rate
:/mnt/hgfs/UbuntuShared/3.4rockx_face_camera_vi$ arm-linux-gnueabihf-gdb ./rockx_face_camera_vi GNU gdb (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)) 8.2.1.20190227-git Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-pc-linux-gnu --target=arm-linux-gnueabihf". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://bugs.linaro.org/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./rockx_face_camera_vi...done. (gdb) target remote 192.168.100.75:1234 Remote debugging using 192.168.100.75:1234 Reading symbols from /opt/rv1126_rv1109_linux_sdk_v1.8.0_20210224/prebuilts/gcc/linux-x86/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/ld-linux-armhf.so.3...done. 0xa6ed0a00 in _start () from /opt/rv1126_rv1109_linux_sdk_v1.8.0_20210224/prebuilts/gcc/linux-x86/arm/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/ld-linux-armhf.so.3 (gdb) break main Breakpoint 1 at 0x11ddc: file rockx_face_camera_vi.cpp, line 76. (gdb) continue Continuing. warning: Could not load shared library symbols for 47 libraries, e.g. /oem/usr/lib/libeasymedia.so.1. Use the "info sharedlibrary" command to see the complete listing. Do you need "set solib-search-path" or "set sysroot"? warning: Could not load shared library symbols for /usr/lib/libv4l/plugins/libv4l-mplane.so. Do you need "set solib-search-path" or "set sysroot"? [New Thread 1096.1913] Thread 1 "rockx_face_came" hit Breakpoint 1, main (argc=1, argv=0xaeb0ed24) at rockx_face_camera_vi.cpp:76 76 memset(&vi_chn_attr, 0, sizeof(VI_CHN_ATTR_S)); (gdb) next 77 vi_chn_attr.pcVideoNode = CAMERA_PATH; // Path (gdb) 78 vi_chn_attr.u32Width = 1920; // Width (gdb) next 79 vi_chn_attr.u32Height = 1080; // Height (gdb) next 80 vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12; // ImageType (gdb) next 81 vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP; // BufType (gdb) next 82 vi_chn_attr.u32BufCnt = 3; // Cnt (gdb) next 83 vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL; // Mode (gdb) next 84 ret = RK_MPI_VI_SetChnAttr(CAMERA_ID, CAMERA_CHN, &vi_chn_attr); (gdb) next 85 if (ret) (gdb) next 87 printf("Vi Set Attr Failed.....\n"); (gdb) next 88 return 0; (gdb) next 92 printf("Vi Set Attr Success.....\n"); (gdb) next 95 ret = RK_MPI_VI_EnableChn(CAMERA_ID, CAMERA_CHN); (gdb) next [New Thread 1096.2089] [New Thread 1096.2090] 96 if (ret) (gdb) next 99 return 0; (gdb) next 103 printf("Vi Enable Attr Success.....\n"); (gdb) next 107 memset(&venc_chn_attr, 0, sizeof(VENC_CHN_ATTR_S)); (gdb) next 110 venc_chn_attr.stVencAttr.u32VirWidth = 1920; (gdb) next 111 venc_chn_attr.stVencAttr.u32VirHeight = 1080; (gdb) next 112 venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12; (gdb) next 113 venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264; (gdb) next [New Thread 1096.2167] 114 venc_chn_attr.stVencAttr.u32Profile = 66; (gdb) next 115 venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR; (gdb) next 121 venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25; (gdb) next 122 ret = RK_MPI_VENC_CreateChn(VENC_CHN, &venc_chn_attr); (gdb) next 123 if (ret) (gdb) next 125 printf("ERROR: Create venc failed!\n"); (gdb) next 126 exit(0); (gdb) next 129 ret = RK_MPI_VI_StartStream(CAMERA_ID, CAMERA_CHN); (gdb) next 130 if (ret) (gdb) next 148 cerr<<"pthread create successed...."<<endl; (gdb) next 151 rockx_config_t *face_detect_config = rockx_create_config(); (gdb) next 152 ret=rockx_add_config(face_detect_config, ROCKX_CONFIG_DATA_PATH, "/userdata/rockx_data"); (gdb) next warning: Could not load shared library symbols for 6 libraries, e.g. /usr/lib32/librknn_runtime.so. Use the "info sharedlibrary" command to see the complete listing. Do you need "set solib-search-path" or "set sysroot"? [New Thread 1096.2250] 153 if (ret != ROCKX_RET_SUCCESS) (gdb) next 155 printf("Failed to add config: error code = %d\n", ret); (gdb) next 160 printf("Invalid parameter: check key or value\n"); (gdb) next 161 break; (gdb) next 163 printf("Memory allocation failed\n"); (gdb) next 164 break; (gdb) next 166 printf("类型不匹配 ...\n"); (gdb) next 175 printf("rockx_add_config successfully\n"); (gdb) next 178 rockx_handle_t face_detect_handle=NULL; (gdb) next 181 printf("第一处断点\n"); (gdb) next 183 rockx_module_t face_detect_module = ROCKX_MODULE_FACE_DETECTION_V2; (gdb) next 187 rockx_release_config(face_detect_config); // 释放配置 (gdb) next 188 printf("第三处断点\n"); (gdb) next 189 if (face_detect_ret != ROCKX_RET_SUCCESS) (gdb) next 191 printf("rockx_create face_detect failed...\n"); (gdb) next 192 return -1; (gdb) next 200 rv1126_rockx_image.width = WIDTH; (gdb) next 201 rv1126_rockx_image.height = HEIGHT; (gdb) next 202 rv1126_rockx_image.pixel_format = ROCKX_PIXEL_FORMAT_YUV420SP_NV12; (gdb) next 203 printf("Image params: width=%d, height=%d, format=%d\n", (gdb) next 206 rv1126_rockx_image.pixel_format); (gdb) next 203 printf("Image params: width=%d, height=%d, format=%d\n", (gdb) next 217 mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VI, CAMERA_CHN, -1); (gdb) next 218 if (!mb) (gdb) next 220 printf("Get Vi Stream break....\n"); (gdb) next 297 RK_MPI_VENC_DestroyChn(VENC_CHN); (gdb) next 298 RK_MPI_VI_DisableChn(CAMERA_ID, CAMERA_CHN); (gdb) next cv::String::String (this=0xaeb0ebe8, s=0x11cc3f "") at ./arm_opencv_source/include/opencv2/core/cvstd.hpp:599 599 if (!s) return; (gdb) next 601 if (!len) return; (gdb) next 603 } (gdb) next cv::String::~String (this=0xa2170b1c <__GI__IO_file_jumps>, __in_chrg=<optimized out>) at ./arm_opencv_source/include/opencv2/core/cvstd.hpp:646 646 String::~String() (gdb) next cv::String::~String (this=0x0, __in_chrg=<optimized out>) at ./arm_opencv_source/include/opencv2/core/cvstd.hpp:648 648 deallocate(); (gdb) next 649 } (gdb) next cv::String::operator= (this=0xa2170b1c <__GI__IO_file_jumps>, str=...) at ./arm_opencv_source/include/opencv2/core/cvstd.hpp:653 653 { (gdb)
06-19
<think>我们正在调试一个名为rockx_face_camera_vi的程序。用户提到了加载共享库符号失败的问题,因此我们需要在启动GDB时确保正确加载共享库的调试符号。步骤:1.确保程序编译时带有调试信息(使用-g选项)。2.启动GDB,加载程序。3.设置环境,以便在运行时加载所需的共享库(如果有必要)。4.设置断点(例如在main函数或特定函数处)。5.运行程序,并在断点处停止。6.单步执行(step/next)和检查变量(print)。7.查看函数调用栈(backtrace)。8.针对共享库符号失败的问题,我们需要确保GDB能够找到共享库的调试符号。根据引用[2],编译时需要加上-g选项,否则会报“Nosymboltableisloaded”错误。另外,如果遇到共享库符号加载失败,我们可以使用GDB的`setsolib-search-path`和`setsolib-absolute-prefix`等命令来设置共享库的搜索路径,或者确保共享库的调试版本可用。具体步骤:1.编译程序时加入调试信息(如果用户已经编译过,可能需要重新编译):gcc-g-orockx_face_camera_virockx_face_camera_vi.c[或其他源文件][链接的库]2.启动GDBgdb./rockx_face_camera_vi3.在GDB中,我们可以设置共享库的搜索路径(如果需要):(gdb)setsolib-search-path/path/to/shared/libraries/(gdb)setsolib-absolute-prefix/path/to/root/for/libraries/4.设置断点,例如在main函数:(gdb)breakmain5.运行程序:(gdb)run6.当程序在断点处停止后,可以单步执行:-使用`step`(或`s`)进入函数内部-使用`next`(或`n`)执行下一行但不进入函数7.打印变量值:(gdb)printvariable_name8.查看函数调用栈:(gdb)backtrace9.如果程序在运行中动态加载共享库(例如通过dlopen),则可能需要使用`setstop-on-solib-events1`命令,以便在加载共享库时暂停,然后手动加载调试符号(如果可用)。10.对于已经加载的共享库,可以使用`infosharedlibrary`查看加载的共享库,然后使用`sharedlibrary[regex]`命令加载匹配的共享库的符号(如果GDB没有自动加载)。11.如果共享库没有调试信息,那么我们将无法看到库中的函数和变量。因此,需要确保有带调试信息的共享库版本。注意:引用[4]提到,调试时系统内核的调试线程会替换断点处的指令,从而实现挂起程序以便调试。下面是一个详细的步骤指南:</think>### 如何使用GDB调试rockx_face_camera_vi程序 #### 一、解决共享库符号加载问题 当出现共享库符号加载失败时: ```bash # 1. 检查程序是否带调试信息编译(必须有-g选项) readelf -S rockx_face_camera_vi | grep debug # 2. 确认共享库路径 ldd rockx_face_camera_vi # 3. 在GDB中手动加载符号 (gdb) info sharedlibrary # 查看未加载符号的库 (gdb) sharedlibrary /path/to/librockx.so # 手动加载符号 (gdb) set solib-search-path /custom/library/path # 设置库搜索路径 ``` #### 二、基础调试流程 ```bash # 启动GDB并加载程序 gdb --args ./rockx_face_camera_vi arg1 arg2 # 设置断点(示例) (gdb) break main # 主函数断点 (gdb) break rockx_face_detect # 关键函数断点 (gdb) break camera.c:120 # 源文件行号断点 # 运行程序 (gdb) run # 或带参数 run --config=test.cfg # 单步调试 (gdb) next # 单步跳过函数 (gdb) step # 单步进入函数 (gdb) finish # 跳出当前函数 (gdb) continue # 继续执行 ``` #### 三、检查函数调用和变量 ```bash # 查看调用栈 (gdb) backtrace # 显示完整调用链 (gdb) frame 2 # 切换到栈帧2 # 检查变量值 (gdb) print camera_handle # 打印基本变量 (gdb) print *ctx@5 # 打印结构体前5个成员 (gdb) p/x buffer_addr # 十六进制格式显示 # 监控变量变化 (gdb) watch frame_counter # 变量修改时中断 (gdb) display image_width # 每次暂停自动显示 ``` #### 四、动态分析技巧 ```bash # 1. 条件断点(当detect_count>100时中断) (gdb) break 185 if detect_count > 100 # 2. 命令自动化(断点时自动执行命令) (gdb) commands 2 >print frame_buffer >backtrace >end # 3. 修改运行值(调试时修复问题) (gdb) set var is_camera_open=1 (gdb) set *(int*)0x7fffdda4 = 1920 # 修改内存值 ``` #### 五、特殊场景处理 1. **多线程调试** ```bash (gdb) info threads # 查看线程 (gdb) thread 3 # 切换到线程3 (gdb) break thread_func:34 thread 3 # 线程专属断点 ``` 2. **信号处理** ```bash (gdb) handle SIGSEGV nostop # 忽略段错误中断 (gdb) catch syscall open # 捕获系统调用 ``` 3. **内存分析** ```bash (gdb) x/32xb frame_buffer # 检查二进制数据 (gdb) p malloc_stats() # 显示堆内存状态(需glibc支持) ``` > **关键原理**:当设置断点时,GDB会将被调试程序的断点地址指令替换为内核的线程挂起指令,执行到此处时OS会挂起程序并转交控制权给调试器[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一道秘制的小菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值