[English | 日本語]
このガイドでは、共有メモリ通信ライブラリでよくある問題とその解決方法を詳しく説明します。問題が発生した時は、該当する症状を見つけて順番に対処法を試してください。
📋 目次
- ビルド・コンパイル問題
- 共有メモリ通信の問題
- Service通信の問題
- Action通信の問題
- パフォーマンス問題
- 環境設定問題
- デバッグツール
🔨 ビルド・コンパイル問題
❌ ヘッダーファイルが見つからない
症状:
fatal error: shm_pub_sub.hpp: No such file or directory
fatal error: shm_service.hpp: No such file or directory
fatal error: shm_action.hpp: No such file or directory
原因と対処法:
# 1. インクルードパスの確認
ls include/
# shm_pub_sub.hpp, udp_comm.hpp などがあることを確認
# 2. コンパイル時のインクルードパス指定
g++ -I./include your_program.cpp
# 3. CMakeLists.txtでの設定
target_include_directories(your_target PRIVATE include)
# 4. 必要なヘッダーファイルの確認
find /path/to/project -name "*.hpp" | grep shm
❌ リンクエラー
症状:
undefined reference to `irlab::shm::Publisher<int>::publish(int const&)'
undefined reference to `irlab::shm::ServiceClient<int,int>::sendRequest(int const&)'
undefined reference to `irlab::shm::ActionClient<int,int,int>::sendGoal(int const&)'
原因と対処法:
# 1. ライブラリファイルの確認
ls build/
# libshm_pub_sub.so, libshm_service.so, libshm_action.so などがあることを確認
# 2. リンク時のライブラリ指定
g++ your_program.cpp -L./build -lshm_pub_sub -lshm_service -lshm_action
# 3. 実行時のライブラリパス設定
export LD_LIBRARY_PATH=./build:$LD_LIBRARY_PATH
❌ C++17エラー
症状:
error: 'std::is_standard_layout_v' was not declared in this scope
対処法:
# C++17対応コンパイラを使用
g++ -std=c++17 your_program.cpp
# またはCMakeで
set(CMAKE_CXX_STANDARD 17)
🧠 共有メモリ通信の問題
❌ データが受信されない(共有メモリ)
症状: subscribe()
でstate
が常にfalse
診断手順:
#include <iostream>
void diagnose_shm_communication() {
using namespace irlab::shm;
std::cout << "=== 共有メモリ通信診断 ===" << std::endl;
try {
Publisher<int> pub("debug_topic");
std::cout << "✅ Publisher作成成功" << std::endl;
pub.publish(42);
std::cout << "✅ データ送信成功" << std::endl;
} catch (const std::exception& e) {
std::cout << "❌ Publisher失敗: " << e.what() << std::endl;
return;
}
try {
Subscriber<int> sub("debug_topic");
std::cout << "✅ Subscriber作成成功" << std::endl;
bool state;
int data = sub.subscribe(&state);
std::cout << "受信結果: state=" << state << ", data=" << data << std::endl;
if (!state) {
std::cout << "❌ データが無効 - 以下を確認:" << std::endl;
std::cout << " - 送信プログラムが動作中か?" << std::endl;
std::cout << " - トピック名が一致しているか?" << std::endl;
}
} catch (const std::exception& e) {
std::cout << "❌ Subscriber失敗: " << e.what() << std::endl;
}
}
出版/購読モデルによるトピック通信を規定するクラスの定義
よくある原因と対処法:
原因 | 対処法 |
トピック名の不一致 | 送信側と受信側で同じ文字列を使用 |
データ型の不一致 | Publisher<int> とSubscriber<int> で型を統一 |
送信プログラムが動いていない | 送信プログラムを先に起動 |
権限問題 | sudo での実行または権限設定 |
❌ 共有メモリアクセスエラー
症状:
terminate called after throwing an instance of 'std::runtime_error'
what(): Failed to create shared memory
対処法:
# 1. 既存の共有メモリセグメントを確認・削除
ipcs -m
# 不要な共有メモリを削除
ipcrm -m [shmid]
# 2. 権限の確認
ls -la /dev/shm/
# shm_* ファイルの権限を確認
# 3. 権限変更(必要に応じて)
sudo chmod 666 /dev/shm/shm_*
🤝 Service通信の問題
❌ 要求応答ができない
症状: Service通信でクライアントが応答を受け取れない
診断手順:
#include <iostream>
#include <thread>
#include <chrono>
void diagnose_service_communication() {
using namespace irlab::shm;
std::cout << "=== Service通信診断 ===" << std::endl;
try {
ServiceServer<int, int> server("debug_service");
std::cout << "✅ ServiceServer作成成功" << std::endl;
if (server.hasRequest()) {
int request = server.getRequest();
server.sendResponse(request * 2);
std::cout << "✅ テスト要求処理成功" << std::endl;
}
} catch (const std::exception& e) {
std::cout << "❌ ServiceServer失敗: " << e.what() << std::endl;
std::cout << "原因の可能性:" << std::endl;
std::cout << " - 共有メモリセグメントの作成失敗" << std::endl;
std::cout << " - サービス名の重複" << std::endl;
return;
}
try {
ServiceClient<int, int> client("debug_service");
std::cout << "✅ ServiceClient作成成功" << std::endl;
client.sendRequest(21);
std::cout << "✅ 要求送信成功" << std::endl;
if (client.waitForResponse(1000000)) {
int response = client.getResponse();
std::cout << "✅ Service通信成功: 21 -> " << response << std::endl;
} else {
std::cout << "❌ 応答タイムアウト" << std::endl;
std::cout << "原因の可能性:" << std::endl;
std::cout << " - サーバーが動作していない" << std::endl;
std::cout << " - サービス名の不一致" << std::endl;
std::cout << " - サーバーの処理が遅い" << std::endl;
}
} catch (const std::exception& e) {
std::cout << "❌ ServiceClient失敗: " << e.what() << std::endl;
}
}
❌ Serviceのタイムアウト問題
症状: クライアントが応答を待つ間にタイムアウトする
対処法:
ServiceClient<int, int> client("slow_service");
client.sendRequest(request_data);
if (client.waitForResponse(10000000)) {
auto response = client.getResponse();
std::cout << "応答受信: " << response << std::endl;
} else {
std::cout << "サービス処理が遅いです" << std::endl;
}
if (client.hasResponse()) {
auto response = client.getResponse();
} else {
}
❌ サービス名の重複
症状: 同じサービス名で複数のサーバーが動作している
診断コマンド:
# 共有メモリセグメントの確認
ipcs -m | grep shm_service
# プロセスの確認
ps aux | grep service
# 重複したサービスの整理
ipcrm -m [shmid] # 不要なセグメントを削除
⚡ Action通信の問題
❌ Actionが開始されない
症状: クライアントがゴールを送信してもアクションが開始されない
診断コード:
#include <iostream>
void diagnose_action_communication() {
using namespace irlab::shm;
std::cout << "=== Action通信診断 ===" << std::endl;
try {
ActionServer<int, int, int> server("debug_action");
std::cout << "✅ ActionServer作成成功" << std::endl;
if (server.hasGoal()) {
auto goal = server.getGoal();
std::cout << "✅ ゴール受信: " << goal << std::endl;
server.setSucceeded(goal * 2);
std::cout << "✅ Action完了" << std::endl;
} else {
std::cout << "❌ ゴールがありません" << std::endl;
}
} catch (const std::exception& e) {
std::cout << "❌ ActionServer失敗: " << e.what() << std::endl;
return;
}
try {
ActionClient<int, int, int> client("debug_action");
std::cout << "✅ ActionClient作成成功" << std::endl;
client.sendGoal(42);
std::cout << "✅ ゴール送信成功" << std::endl;
if (client.waitForResult(5000000)) {
auto result = client.getResult();
std::cout << "✅ Action結果受信: " << result << std::endl;
} else {
std::cout << "❌ Actionタイムアウト" << std::endl;
}
} catch (const std::exception& e) {
std::cout << "❌ ActionClient失敗: " << e.what() << std::endl;
}
}
⚡ パフォーマンス問題
❌ 通信が遅い
症状: 期待より通信速度が遅い
診断と対処法:
#include <chrono>
#include <vector>
void measure_performance() {
using namespace std::chrono;
{
using namespace irlab::shm;
Publisher<int> pub("perf_test");
Subscriber<int> sub("perf_test");
const int iterations = 10000;
auto start = high_resolution_clock::now();
for (int i = 0; i < iterations; ++i) {
pub.publish(i);
bool state;
sub.subscribe(&state);
}
auto end = high_resolution_clock::now();
auto duration = duration_cast<microseconds>(end - start);
std::cout << "共有メモリ通信:" << std::endl;
std::cout << " 総時間: " << duration.count() << " μs" << std::endl;
std::cout << " 1回あたり: " << duration.count() / iterations << " μs" << std::endl;
}
{
using namespace irlab::udp;
Sender<int> sender("perf_test");
Receiver<int> receiver("perf_test");
const int iterations = 1000;
auto start = high_resolution_clock::now();
for (int i = 0; i < iterations; ++i) {
sender.send(i);
receiver.waitFor(10000);
bool state;
receiver.receive(&state);
}
auto end = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(end - start);
std::cout << "UDP通信:" << std::endl;
std::cout << " 総時間: " << duration.count() << " ms" << std::endl;
std::cout << " 1回あたり: " << duration.count() / (double)iterations << " ms" << std::endl;
}
}
パフォーマンス改善方法:
通信方式 | 改善方法 |
共有メモリ | ・CPUアフィニティ設定
・リアルタイムプロセス優先度
・不要なシステム負荷削減 |
UDP | ・送信間隔の調整
・バッファサイズ最適化
・ネットワーク設定確認 |
🔧 環境設定問題
❌ 権限エラー
症状:
Permission denied
Failed to create shared memory segment
対処法:
# 1. ユーザーをshm可能グループに追加
sudo usermod -a -G audio $USER # または適切なグループ
# 2. 一時的な権限変更
sudo chmod 777 /dev/shm
# 3. systemd設定(永続的)
# /etc/systemd/system.conf に追加
DefaultLimitMEMLOCK=infinity
❌ 依存関係問題
症状: 必要なライブラリが見つからない
対処法:
# Ubuntu/Debian
sudo apt update
sudo apt install build-essential cmake libboost-all-dev python3-dev
# CentOS/RHEL
sudo yum groupinstall "Development Tools"
sudo yum install cmake boost-devel python3-devel
# 依存関係確認
ldd your_program
🔍 デバッグツール
共有メモリ監視ツール
#!/bin/bash
# shm_monitor.sh - 共有メモリ監視スクリプト
echo "=== 共有メモリ使用状況 ==="
echo "システム全体:"
ipcs -m
echo ""
echo "SHMライブラリ関連:"
ls -la /dev/shm/ | grep shm_
echo ""
echo "プロセス監視:"
ps aux | grep -E "(your_program_name|shm)"
Service/Action状態診断ツール
#!/bin/bash
# service_action_debug.sh - Service/Action通信診断スクリプト
SERVICE_NAME=${1:-"test_service"}
echo "=== Service/Action通信診断 (Service: $SERVICE_NAME) ==="
echo "1. 共有メモリセグメント:"
ipcs -m | grep -E "(shm_service|shm_action)" || echo "サービス関連セグメントはありません"
echo ""
echo "2. 関連プロセス:"
ps aux | grep -E "(service|action)" | grep -v grep || echo "関連プロセスはありません"
echo ""
echo "3. メモリ使用量:"
free -h
echo ""
echo "4. システムロード:"
uptime
echo ""
echo "5. システムログエラー:"
dmesg | tail -10 | grep -i error || echo "最近のエラーはありません"
ログ出力設定
#ifndef DEBUG_LOGGER_HPP
#define DEBUG_LOGGER_HPP
#include <iostream>
#include <fstream>
#include <chrono>
#include <iomanip>
class DebugLogger {
public:
static DebugLogger& getInstance() {
static DebugLogger instance;
return instance;
}
template<typename... Args>
void log(Args&&... args) {
auto now = std::chrono::system_clock::now();
auto time_t = std::chrono::system_clock::to_time_t(now);
std::cout << "[" << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S") << "] ";
(std::cout << ... << args) << std::endl;
if (log_file_.is_open()) {
log_file_ << "[" << std::put_time(std::localtime(&time_t), "%Y-%m-%d %H:%M:%S") << "] ";
(log_file_ << ... << args) << std::endl;
log_file_.flush();
}
}
void enableFileLogging(const std::string& filename) {
log_file_.open(filename, std::ios::app);
}
private:
std::ofstream log_file_;
};
#define DEBUG_LOG(...) DebugLogger::getInstance().log(__VA_ARGS__)
#endif
📞 サポートが必要な場合
情報収集
問題が解決しない場合は、以下の情報を収集してサポートチームにお知らせください:
# システム情報収集スクリプト
#!/bin/bash
# collect_info.sh
echo "=== システム情報 ==="
uname -a
lsb_release -a 2>/dev/null || cat /etc/os-release
echo ""
echo "=== コンパイラ情報 ==="
g++ --version
cmake --version
echo ""
echo "=== ライブラリ情報 ==="
find . -name "*.so" -exec ls -la {} \;
echo ""
echo "=== 共有メモリ状況 ==="
ipcs -m
ls -la /dev/shm/ | grep shm_
echo ""
echo "=== システムリソース ==="
free -h
df -h /dev/shm
echo ""
echo "=== 関連プロセス状況 ==="
ps aux | grep -E "(your_program|shm|service|action)" | grep -v grep
エラーレポート形式
【問題の症状】
・どのような動作を期待していたか
・実際にはどうなったか
・エラーメッセージ(あれば)
【環境情報】
・OS: Ubuntu 20.04
・コンパイラ: g++ 9.4.0
・使用ライブラリ: shm_pub_sub, shm_service, shm_action v1.0
【再現手順】
1. プログラムをコンパイル
2. 送信プログラムを実行
3. 受信プログラムを実行
4. → データが受信されない
【試したこと】
・共有メモリセグメントの確認 (ipcs -m)
・トピック名/サービス名の確認
・プロセスの起動順序確認
・...
このガイドで問題が解決しない場合は、遠慮なくサポートチームまでお問い合わせください! 🚀