鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    Segmentation fault (Address not mapped to object [(nil)])

    已定时 已固定 已锁定 已移动
    ROS 2相关问题
    ros2humble c++
    2
    6
    1.1k
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • yudonghou123Y
      小猴同学
      最后由 编辑

      大佬们,救救孩子吧,一天了,请问这是怎么回事,我用GDB调试,程序输出以下问题

      Stack trace (most recent call last):
      #10   Object "[0xffffffffffffffff]", at 0xffffffffffffffff, in 
      #9    Object "/home/user7/auv533_ws/install/auv_socket/lib/auv_socket/usbl_data_pub", at 0x55e9f1cc8254, in 
      #8    Object "/lib/x86_64-linux-gnu/libc.so.6", at 0x7f2d54e29e3f, in __libc_start_main
      #7    Object "/lib/x86_64-linux-gnu/libc.so.6", at 0x7f2d54e29d8f, in 
      #6    Object "/home/user7/auv533_ws/install/auv_socket/lib/auv_socket/usbl_data_pub", at 0x55e9f1cc812f, in 
      #5    Object "/opt/ros/humble/lib/librclcpp.so", at 0x7f2d5562524e, in rclcpp::spin(std::shared_ptr<rclcpp::Node>)
      #4    Object "/opt/ros/humble/lib/librclcpp.so", at 0x7f2d55625154, in rclcpp::spin(std::shared_ptr<rclcpp::node_interfaces::NodeBaseInterface>)
      #3    Object "/opt/ros/humble/lib/librclcpp.so", at 0x7f2d55624f3f, in rclcpp::executors::SingleThreadedExecutor::spin()
      #2    Object "/opt/ros/humble/lib/librclcpp.so", at 0x7f2d5561d650, in rclcpp::Executor::execute_any_executable(rclcpp::AnyExecutable&)
      #1    Object "/home/user7/auv533_ws/install/auv_socket/lib/auv_socket/usbl_data_pub", at 0x55e9f1ccca44, in 
      #0    Object "/home/user7/auv533_ws/install/auv_socket/lib/auv_socket/usbl_data_pub", at 0x55e9f1cdbbad, in 
      Segmentation fault (Address not mapped to object [(nil)])
      [ros2run]: Segmentation fault
      

      救救孩子吧

      芜湖

      小鱼小 1 条回复 最后回复 回复 引用 0
      • 小鱼小
        小鱼 技术大佬 @yudonghou123
        最后由 编辑

        @yudonghou123 你的程序编译的时候应该没有debug模式,显示不出具体代码

        新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

        yudonghou123Y 1 条回复 最后回复 回复 引用 0
        • yudonghou123Y
          小猴同学 @小鱼
          最后由 yudonghou123 编辑

          @小鱼 您好,我测试出是哪个地方的问题了,我目前想在一个cpp文件中发布多个话题,但是在发布另一个话题时总是出现上面的问题,您能帮我看看程序的问题吗?

          #include <memory>
          #include <iostream>
          #include <fstream>
          #include <iomanip>
          #include "rclcpp/rclcpp.hpp"
          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>
          #include <sys/socket.h>
          #include <sys/types.h>
          #include <unistd.h>
          #include <arpa/inet.h>
          #include <netinet/in.h>
          #include <fcntl.h>
          #include <list>
          #include <ctime>
          #include <time.h>
          #include <sys/shm.h>
          #include "auv_msgs/msg/usbl.hpp"
          #include "auv_msgs/msg/shorebased.hpp"
          #include <vector>
          #include "auv_socket/USBL_STRUCT.h"
          #include "auv_socket/USBL_SHOREBASED.h"
          #include "std_msgs/msg/bool.hpp"
          // 通过socket通信接收数据,并实现USBL数据传输发布,发布话题名称为usbl_data
          // 信息格式:auv_msgs/msg/USBL
          ofstream usblfile;
          string usblfilename;
          // 设置端口和数据长度
          #define PORT 29
          #define DATASIZE 1024
          #define BUFSIZE 40960
          // 23 DVL    26 IMU    29 USBL     32 BDS
          // 设置IP地址
          char *SERVER_IP = "192.168.0.7";
          using namespace std;
          using namespace std::chrono_literals;
          
          class usbl_data_pub : public rclcpp::Node
          {
          public:
          	usbl_data_pub() : Node("usbl_data_pub")
          	{
          		// 创建输出文件时间前缀
          		time_t now;
          		struct tm *usbl_time_info;
          		char usbl_time[20];
          		time(&now);
          		usbl_time_info = localtime(&now);
          		strftime(usbl_time, sizeof(usbl_time), "%Y%m%d%H%M%S", usbl_time_info);
          		string usbltime(usbl_time);
          		usblfilename = "txt/usbldata/usbldata_" + usbltime + ".txt";
          		ofstream usblfile(usblfilename);
          		if (!usblfile.is_open())
          		{
          			RCLCPP_ERROR(this->get_logger(), "USBL FILE OPEN ERROR");
          		}
          		 // 创建回调组
                  callback_group_1 = this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
                  auto pub_opt_1 = rclcpp::PublisherOptions();
                  pub_opt_1.callback_group = callback_group_1;
                  callback_group_2 = this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
                  auto pub_opt_2 = rclcpp::PublisherOptions();
                  pub_opt_1.callback_group = callback_group_2;
          		// 创建发布对象
          		usbl_publisher_ = this->create_publisher<auv_msgs::msg::USBL>("usbl_data", 100,pub_opt_1);
          		usbl_parse_pub = this->create_publisher<auv_msgs::msg::SHOREBASED>("usbl_parsedata", 100,pub_opt_2);
          		usbl_flag_pub = this->create_publisher<std_msgs::msg::Bool>("usbl_response", 100,pub_opt_1);
          		usbl_timer_ = this->create_wall_timer(1s, std::bind(&usbl_data_pub::usbl_time_callback, this),callback_group_1);
          	}
          
          private:
          	void usbl_time_callback()
          	{ // socket通讯,创建socket对象和连接
          		char recvbuf[BUFSIZE];
          		int socket_cli = socket(AF_INET, SOCK_STREAM, 0);
          		if (socket_cli < 0)
          		{
          			RCLCPP_ERROR(this->get_logger(), "USBL SOCKET ERROR");
          		}
          		struct sockaddr_in sev_addr;
          		memset(&sev_addr, 0, sizeof(sev_addr));
          		sev_addr.sin_family = AF_INET;
          		sev_addr.sin_port = htons(PORT);
          		sev_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
          
          		// 判断是否连接成功
          		if (connect(socket_cli, (struct sockaddr *)&sev_addr, sizeof(sev_addr)) < 0)
          		{
          			RCLCPP_ERROR(this->get_logger(), "USBL CONNECT ERROR");
          		}
          		else
          		{
          			RCLCPP_INFO(this->get_logger(), "USBL CONNECTED SUCCESS");
          		}
          		recvFlag = false;
          		while (rclcpp::ok())
          		{
          			// 接收来自socket缓冲区的信息
          			recv(socket_cli, recvbuf, sizeof(recvbuf), 0);
          			RCLCPP_INFO(this->get_logger(), "%s", recvbuf);
          			// 创建USBL的消息腹部格式并赋值发布
          			auto usbl_data = auv_msgs::msg::USBL();
          			auto usbl_response = std_msgs::msg::Bool();
          			auto usbl_parse_msg = auv_msgs::msg::SHOREBASED();
          			usbl_response.data = recvFlag;
          			// usbl_flag_pub->publish(usbl_response);
          			//  usbl_data.header.frame_id = "usbl_link";
          			rclcpp::Time usbl_right_time = this->get_clock()->now();
          			usbl_data.usbl_sys_time = usbl_right_time.seconds();
          			// usbl_data.header.stamp = usbl_right_time;
          			unsigned char data[BUFSIZE] = {0};
          			const char *split = "$"; // 使用,割符对接收到的数据进行分割
          			char *buf;
          			char *p = strtok(recvbuf, split);
          			while (p != NULL)
          			{
          				buf = p; // 将获得的数据赋给buf,并将其从16进制转为ASCII,赋值给data数组
          				for (int i = 0; i < strlen(buf); i += 2)
          				{
          					unsigned char c = 0;
          					unsigned char a = buf[i];	  // 第一位
          					unsigned char b = buf[i + 1]; // 后一位
          					if (a <= '9' && a >= '0')
          						c = a - '0'; // zhuanma
          					else if (a <= 'F' && a >= 'A')
          						c = a - 'A' + 10;
          					else if (a <= 'f' && a >= 'a')
          						c = a - 'a' + 10;
          					else
          						break;
          					c = c << 4;
          					if (b <= '9' && b >= '0')
          						c += b - '0';
          					else if (b <= 'F' && b >= 'A')
          						c += b - 'A' + 10;
          					else if (b <= 'f' && b >= 'a')
          						c += b - 'a' + 10;
          					else
          						break;
          					data[i >> 1] = c;
          				}
          				// 确定数据类型
          				// 150向110发送数据,150发送成功,110接收失败,150反馈收到32和63的数据,110显示32
          				// 单$32 110发送成功,150接收不到  $32 $63 150发送失败
          				// 110PING150或者向150发送数据,或者150向110发送数据,其反馈的以$39开头的数据其均未包含任何信息,
          				// 只有150PING110时,以$39开头的数据才包含角度,距离信息
          				// 考虑反馈返回的数据程序是否冲突
          				switch (data[0])
          				{
          				case 0x32:
          				{
          					// 如果出现32数据,说明110向150发送数据,150接收不成功
          					RCLCPP_ERROR(this->get_logger(), "Message sent when the transceiver receiver encounters an error");
          					break;
          				}
          				case 0x35:
          				{
          					// 如果出现35数据说明150向110发送数据,110已经接收代码未处理
          					RCLCPP_INFO_ONCE(this->get_logger(), "Message sent when the transceiver receives a response (to a transmitted request).");
          					break;
          				}
          				case 0x38:
          				{
          					// USBL自身设备信息
          					CID_XCVR_USBL tmpt;
          					const unsigned char *q = data;
          					tmpt = CID_XCVR_USBL(q);
          					break;
          				}
          				case 0x39:
          				{
          					// 读取USBL相对信息
          					CID_XCVR_FIX tmpt;
          					const unsigned char *q = data;
          					tmpt = CID_XCVR_FIX(q);
          					usbl_data.beacon_id = tmpt.ACO_FIX.DEST_ID;
          					usbl_data.local_depth = tmpt.ACO_FIX.DEPTH_LOCAL;
          					usbl_data.usbl_vos = tmpt.ACO_FIX.VOS / 10.0;
          					usbl_data.usbl_roll = tmpt.ACO_FIX.ATTITUDE_ROLL / 10.0;
          					// 通过此标志符号判断39数据是由PING产生的还是发送数据60产生的,不是PING产生的订阅时产生的数据为0
          					// 发送60数据产生的39数值错误
          					if (tmpt.ACO_FIX.FLAGS & 0x01)
          					{
          						usbl_data.range_count = tmpt.ACO_FIX.RANGE_FIELD.RANGE_COUNT;
          						usbl_data.range_time = tmpt.ACO_FIX.RANGE_FIELD.RANGE_TIME;
          						usbl_data.range_dist = tmpt.ACO_FIX.RANGE_FIELD.RANGE_DIST / 10.0 / 2.0;
          					}
          					if (tmpt.ACO_FIX.FLAGS & 0x02)
          					{
          						usbl_data.usbl_pitch = tmpt.ACO_FIX.USBL_FIELD.USBL_ELEVATION / 10.0;
          						usbl_data.usbl_yaw = tmpt.ACO_FIX.USBL_FIELD.USBL_AZIMUTH / 10.0;
          					}
          					if (tmpt.ACO_FIX.FLAGS & 0x04)
          					{
          						usbl_data.position_east = tmpt.ACO_FIX.POSITION_FIELD.POSITION_EASTING / 10.0 / 2.0;
          						usbl_data.position_north = tmpt.ACO_FIX.POSITION_FIELD.POSITION_NORTHING / 10.0 / 2.0;
          						usbl_data.position_depth = tmpt.ACO_FIX.POSITION_FIELD.POSITION_DEPTH / 10.0 / 2.0;
          					}
          					usbl_publisher_->publish(usbl_data);
          					// 将数据保存进txt文件中
          					usblfile.open(usblfilename, ios::out | ios::app);
          					usblfile << usbl_data.usbl_sys_time << " ";
          					usblfile << fixed << setprecision(4) << usbl_data.usbl_pitch << " " << usbl_data.usbl_yaw << " " << usbl_data.position_east << " " << usbl_data.position_north << " " << usbl_data.position_depth << endl;
          					usblfile.close();
          					break;
          				}
          				case 0x43:
          				{
          					// 如果出现43数据,说明150PING110不成功代码未处理
          					RCLCPP_ERROR(this->get_logger(), "Message sent when a PING response error/timeout occurs");
          					break;
          				}
          				case 0x60:
          				{
          					// 150 向110发送成功反馈,不管110是否已经接收成功
          					// usbl_response.data = false;
          					// usbl_flag_pub->publish(usbl_response);
          					recvFlag = false;
          					RCLCPP_INFO(this->get_logger(), "Message sent to transmit a datagram to another beacon).");
          					break;
          				}
          				case 0x61:
          				{
          					// 解析110发送给150的数据
          					// 注意格式61数据产生的39指令不包含位姿角度和东北天向距离
          					// CID_DAT_RECEIVE tmpt;
          					const unsigned char *q = data;
          					USBL_DATA_PARSE(data);
          					break;
          				}
          				case 0x63:
          				{
          					// 标志150向110发送信息失败,代码未处理
          					RCLCPP_ERROR(this->get_logger(), "Message generated when a beacon response error/timeout occurs for ACKs.");
          					break;
          				}
          				default:
          					break;
          				}
          				p = strtok(NULL, split);
          			}
          		}
          		close(socket_cli);
          	}
          	void USBL_DATA_PARSE(const unsigned char *data)
          	{
          		auto usbl_parse_msg = auv_msgs::msg::SHOREBASED();
          		CID_DAT_RECEIVE tmpt;
          		tmpt = CID_DAT_RECEIVE(data);
          		if (tmpt.PACKET_DATA[0] == 10 && tmpt.PACKET_LEN == 15)
          		{
          			// recvFlag = true;
          			usbl_parse_msg.nextpos[0] = tmpt.PACKET_DATA[1];																								  // 当前路径点总个数
          			usbl_parse_msg.nextpos[1] = tmpt.PACKET_DATA[2];																								  // 当前路径点位数
          			usbl_parse_msg.nextpos[2] = ((tmpt.PACKET_DATA[3] + (tmpt.PACKET_DATA[4] << 8) + (tmpt.PACKET_DATA[5] << 16) + (tmpt.PACKET_DATA[6] << 24)));	  // 纬度
          			usbl_parse_msg.nextpos[3] = ((tmpt.PACKET_DATA[7] + (tmpt.PACKET_DATA[8] << 8) + (tmpt.PACKET_DATA[9] << 16) + (tmpt.PACKET_DATA[10] << 24)));	  // 经度
          			usbl_parse_msg.nextpos[4] = ((tmpt.PACKET_DATA[11] + (tmpt.PACKET_DATA[12] << 8) + (tmpt.PACKET_DATA[13] << 16) + (tmpt.PACKET_DATA[14] << 24))); // 高度
          			usbl_parse_pub->publish(usbl_parse_msg);																																				  // usbl_parse_pub->publish(usbl_parse_msg);
          		}
          	}
          	rclcpp::Publisher<std_msgs::msg::Bool>::SharedPtr usbl_flag_pub;
          	rclcpp::TimerBase::SharedPtr usbl_timer_;
          	rclcpp::Publisher<auv_msgs::msg::USBL>::SharedPtr usbl_publisher_;
          	rclcpp::Publisher<auv_msgs::msg::SHOREBASED>::SharedPtr usbl_parse_pub;
          	rclcpp::CallbackGroup::SharedPtr callback_group_1;
              rclcpp::CallbackGroup::SharedPtr callback_group_2;
          };
          
          int main(int argc, char *argv[])
          {
          	rclcpp::init(argc, argv);
          	// rclcpp::spin(std::make_shared<usbl_data_pub>());
          	rclcpp::executors::MultiThreadedExecutor executor;
              auto usbl_data_pub_node = std::make_shared<usbl_data_pub>();
              executor.add_node(usbl_data_pub_node);
              executor.spin();
          	rclcpp::shutdown();
          	return 0;
          }
          

          程序在发布话题时出现问题,我把话题发布注释掉就可行了,但是目前我想发布这个话题

          void USBL_DATA_PARSE(const unsigned char *data)
          	{
          		auto usbl_parse_msg = auv_msgs::msg::SHOREBASED();
          		CID_DAT_RECEIVE tmpt;
          		tmpt = CID_DAT_RECEIVE(data);
          		if (tmpt.PACKET_DATA[0] == 10 && tmpt.PACKET_LEN == 15)
          		{
          			// recvFlag = true;
          			usbl_parse_msg.nextpos[0] = tmpt.PACKET_DATA[1];																								  // 当前路径点总个数
          			usbl_parse_msg.nextpos[1] = tmpt.PACKET_DATA[2];																								  // 当前路径点位数
          			usbl_parse_msg.nextpos[2] = ((tmpt.PACKET_DATA[3] + (tmpt.PACKET_DATA[4] << 8) + (tmpt.PACKET_DATA[5] << 16) + (tmpt.PACKET_DATA[6] << 24)));	  // 纬度
          			usbl_parse_msg.nextpos[3] = ((tmpt.PACKET_DATA[7] + (tmpt.PACKET_DATA[8] << 8) + (tmpt.PACKET_DATA[9] << 16) + (tmpt.PACKET_DATA[10] << 24)));	  // 经度
          			usbl_parse_msg.nextpos[4] = ((tmpt.PACKET_DATA[11] + (tmpt.PACKET_DATA[12] << 8) + (tmpt.PACKET_DATA[13] << 16) + (tmpt.PACKET_DATA[14] << 24))); // 高度
          			usbl_parse_pub->publish(usbl_parse_msg);																																				  // usbl_parse_pub->publish(usbl_parse_msg);
          		}
          	}
          

          芜湖

          小鱼小 2 条回复 最后回复 回复 引用 0
          • 小鱼小
            小鱼 技术大佬 @yudonghou123
            最后由 编辑

            @yudonghou123 建议debug到具体哪一行挂掉的,这样方便找到问题

            新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

            yudonghou123Y 1 条回复 最后回复 回复 引用 0
            • yudonghou123Y
              小猴同学 @小鱼
              最后由 编辑

              @小鱼 您好,我的终端是这样报错的

              Thread 1 "usbl_parse_pub" received signal SIGSEGV, Segmentation fault.
              0x0000555555567ab6 in usbl_parse_pub::USBL_DATA_PARSE (this=0x555555640430, data=0x7fffffff2f6e "\fZ\003") at /home/user7/auv533_ws/src/auv_socket/src/usbl_parse_pub.cpp:175
              175             if (tmpt.PACKET_DATA[0] == 10 && tmpt.PACKET_LEN == 15)
              (gdb)
              

              芜湖

              1 条回复 最后回复 回复 引用 0
              • 小鱼小
                小鱼 技术大佬 @yudonghou123
                最后由 编辑

                @yudonghou123 在 Segmentation fault (Address not mapped to object [(nil)]) 中说:

                if (tmpt.PACKET_DATA[0] == 10 && tmpt.PACKET_LEN == 15)

                有没有一种可能,我说是一种可能,tmpt 是空的数组

                新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

                1 条回复 最后回复 回复 引用 0
                • 第一个帖子
                  最后一个帖子
                皖ICP备16016415号-7
                Powered by NodeBB | 鱼香ROS