首页 > 编程语言 > 5、开发环境-调试C/C++控制器

5、开发环境-调试C/C++控制器

时间:2023-07-27 11:55:56浏览次数:44  
标签:控制器 00 C++ gdb Webots soccer pts 调试

控制器处理

在Webots环境中,Webots应用程序和每个机器人C/C++控制器在不同的操作系统进程中执行。例如,当执行“soccer.wbt”世界时,内存中总共有八个进程;一个用于Webots,六个用于六个玩家机器人,一个用于监督机器人。若要使用Microsoft Visual Studio调试C/C++控制器,请参阅此处。
当控制器进程执行非法指令时,操作系统会终止该指令,而Webots进程和其他控制器进程仍处于活动状态。尽管Webots仍然处于活动状态,但由于它在等待来自终止的控制器的数据,因此模拟会被阻止。因此,如果您遇到模拟意外停止,但Webots GUI仍有响应的情况,这通常表明控制器已崩溃。这可以很容易地通过列出此时的活动进程来确认:例如,在Linux上,键入:

$ ps -e
...
12751 pts/1    00:00:16 webots
13294 pts/1    00:00:00 soccer_player
13296 pts/1    00:00:00 soccer_player
13297 pts/1    00:00:00 soccer_player
13298 pts/1    00:00:00 soccer_player
13299 pts/1    00:00:00 soccer_player
13300 pts/1    00:00:00 soccer_player
13301 pts/1    00:00:00 soccer_supervisor <defunct>
...

在macOS上,使用ps-x,在Windows上使用任务管理器。如果您的一个机器人控制器在列表中丢失(或显示为无效),则确认它已崩溃,因此阻止了模拟。在本例中,“soccer_supersvisor”已崩溃。请注意,控制器的崩溃几乎肯定是由控制器代码中的错误引起的,因为Webots中的错误会导致Webots崩溃。幸运的是,GNU调试器(gdb)通常可以帮助查找崩溃的原因。以下示例假设“soccer_supersvisor”控制器存在问题,并指示如何进行调试。

将GNU调试器与控制器一起使用

第一步是使用调试目标重新编译控制器,以便将调试信息添加到可执行文件中。您必须直接在终端中重新编译控制器,因为Webots文本编辑器“构建”按钮将从构建中省略调试信息:

$ make clean
$ make debug
...

重新编译控制器后,需要确保Robot节点的控制器设置为外部控制器。如果不是,则可以从场景树中进行设置:单击“暂停”和“重置”按钮,将Robot节点的控制器字段设置为<extern>,然后保存世界文件。从终端,转到包含控制器程序的文件夹,并用gdb启动它:

$ gdb my_controller

在gdb中,例如输入如下:

(gdb) break my_controller.c:50
(gdb) run

然后,使用run按钮(也可以使用Step、Real Time或Fast按钮)运行Webots模拟。您的控制器程序将开始控制Webots中的外部机器人。一旦到达断点,您将能够查询变量、设置新的断点等。
然后,cont命令将指示调试器恢复进程的执行。您也可以使用步骤功能逐步进行。
控制器的执行可以随时中断(ctrl-C),以便查询变量、设置断点等。当发生崩溃时,gdb会打印类似于以下的诊断消息:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208314144 (LWP 16448)]
0x00cd6dd5 in _IO_str_overflow_internal () from /lib/tls/libc.so.6

这表示问题的位置。您可以使用gdb的where命令来更精确地检查调用堆栈。例如类型:

gdb) where
#0 0x00cd6dd5 in _IO_str_overflow_internal() from /lib/tls/libc.so.6
#1 0x00cd596f in _IO_default_xsputn_internal() from /lib/tls/libc.so.6
#2 0x00cca9c1 in _IO_padn_internal() from /lib/tls/libc.so.6
#3 0x00cb17ea in vfprintf() from /lib/tls/libc.so.6
#4 0x00ccb9cb in vsprintf() from /lib/tls/libc.so.6
#5 0x00cb8d4b in sprintf() from /lib/tls/libc.so.6
#6 0x08048972 in run(duration=0) at soccer_supervisor.c:106
#7 0x08048b0a in main() at soccer_supervisor.c:140

通过仔细检查调用堆栈,您可以找到错误的来源。在这个例子中,我们将假设sprintf函数是可以的,因为它在系统库中。因此,问题似乎是由run函数中非法使用sprintf函数引起的。必须仔细检查源文件“soccer_supersvisor.c”的第106行。当控制器仍在内存中时,您可以查询一些变量的值,以了解发生了什么。例如,可以使用框架和打印命令:

(gdb) frame 6
#6  0x08048953 in run (duration=0) at soccer_supervisor.c:106
106         sprintf(time_string, "%02d:%02d", (int) (time / 60),
 (int) time % 60);
(gdb) print time_string
$1 = 0x0

frame命令指示调试器选择指定的堆栈帧,print命令打印表达式的当前值。在这个简单的例子中,我们清楚地看到问题是由传递给sprintf函数的NULL(0x0)time_string参数引起的。接下来的步骤是:

  1. Fix the problem
  2. Recompile the controller
  3. Reload the world to give it another try.
 一旦它工作并给出正确的输出,您就可以从Makefile中删除-g标志。

 

 

 

 

 

 

 

 

 

 

 

 

 

标签:控制器,00,C++,gdb,Webots,soccer,pts,调试
From: https://www.cnblogs.com/gary-guo/p/17584576.html

相关文章

  • [glibc2.23源码]阅读源码&调试,找出free_hook-0x13分配失败的原因
    0x00写在前面2023.7.27早合肥本次阅读源码是本人第一次,算是一个全新的开始。本次看源码是为了调试roarctf的babyheap那道题目,wp写在独奏者2序章那篇的0x04,为了看看为什么free_hook-0x13不能分配堆。0x01阅读前言和别名搜索aliasweak_alias(__malloc_info,malloc_info......
  • 《c++徒步》串口篇
    串口和USB串口是指通过串行传输数据的接口,它使用少量的引脚来传输数据。串口通常以RS-232(常见的是DB9或DB25连接器)或RS-485等协议进行通信。串口常用于连接计算机和外部设备,例如调制解调器、打印机、传感器等。USB是一种通用的连接标准,用于连接各种外部设备到计算机或其他主机设......
  • C++中的模板
    1.概念模板是对类型的抽象,为了更好的实现多态的思想。模板分为类模板和函数模板。2.函数模板就是在函数之前声明一下模板,然后执行的时候,函数自行判断推导类型。intadd(inta,intb){returna+b;}doubleadd(doublea,doubleb){returna+b;}//如a......
  • c++ std::thread::joinable
    std:......
  • c++
    /*#include<iostream>usingnamespacestd;intmain(){intn; intb; intc=0;cin>>n;inta[n];for(inti=0;i<n;i++){cin>>a[i];}for(inti=0;i<n;i++){for(intj=0;j<n-i-1;j++){......
  • c++学习:封装、继承、多态
    c++是面向对象的编程语言,相对于c具有封装、继承、多态的特点。封装定义:封装就是将对象的属性和行为封装起来,形成一个有机的整体,其载体就是类。类通常对客户隐藏其实现细节,这就是封装的思想,就比如我们使用一个库函数时,我们只需要知道它的作用就可以了,没必要去了解它的内部工......
  • 小熊猫 C++ 的 Monokai 改进
    小熊猫目前自带的配色方案Monokai:发现很丑,根本不是想象中的Monokai!!!网上也没有相关的配置,于是自己花了一下午弄了个Monokai:下载地址解压后直接在配色里面导入即可。具体步骤:工具-选项-编辑器配色-导入配色-选中解压后的文件-确定。是不是好看多了?还支持自定义......
  • c++学习:程字辈(进程、线程、协程)
    程字辈(进程、线程、协程)介绍C++中的进程、线程、协程之间的联系及区别。(以linux下实现为例)进程概念:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。每个进程都有自己的独立内存空间,不同进程通过进程间通信来......
  • C/C++代码混淆器
    C/C++代码混淆器试图通过混淆C/C++源代码以达到保护知识产权的目的的做法其实就是自欺欺人,因为不论如何混淆代码,到了编译阶段代码终究是要被还原成它本来的样子,说到底,这只是一层窗户纸而已。我曾利用宏机制实现过一个C/C++代码混淆器,效果乍一看还真能给人一种眼前一亮的神奇,......
  • C#引用c++ DLL找不到入口点
    c++中的函数名称在编译后改变了,需要利用dumpbin.exe找到编译后的名字dumpbin.exe在VS安装目录参考路径:C:\ProgramFiles(x86)\MicrosoftVisualStudio\2019\Community\VC\Tools\MSVC\14.28.29910\bin\Hostx64\x64打开cmd,移动到dumpbin.exe对应路径,然后输入命令dumpbin-e......