apache / celix

Apache Celix is a framework for C and C++14 to develop dynamic modular software applications using component and in-process service-oriented programming.
https://celix.apache.org/
Apache License 2.0
158 stars 85 forks source link

How to debug bundles with GDB #706

Closed tonychen0924 closed 6 months ago

tonychen0924 commented 6 months ago

When I build my process , CMakeLists.txt also add set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") But when I run exe with gdb and set break , can not find my source file . Does the bundle not support GDB debugging or does it require specific settings ?

r$ gdb ./MyContainer GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1 Copyright (C) 2022 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 "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: https://www.gnu.org/software/gdb/bugs/. 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 ./MyContainer... (gdb) b plc_main.c:8 No source file named plc_main.c. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (plc_main.c:8) pending.

NOTE: This issue is caused by an incorrect way of setting up the debug build for a mixed C/C++ CMake project.

tonychen0924 commented 6 months ago

“b function” also can not find

PengZheng commented 6 months ago

Add -DCMAKE_BUILD_TYPE:STRING=Debug to your CMake command line, then CMake should take care of everything. This seems not Celix-related but a general CMake question, which may better be raised on sites like StackOverflow.

Debugging a bundle is no different than debugging any other shared libraries opened by dlopen. If you are not sure how to do that, I suggest you write a basic hello world shared library and 10 lines main which uses it via dlopen, then try using gdb to debug it. This really has nothing special to do with Celix.

Before posting an issue, please take time to consider whether it is really a Celix issue.

PengZheng commented 6 months ago

(gdb) b plc_main.c:8 No source file named plc_main.c.

You forget to run your program (I saw no gdb run command). If your program has not loaded a bundle by dlopen, how could it be able to get the debugging information embedded in a shared library and thus get to know the location of the associated source file? Bundled are shared library, but they are dynamically loaded, not loaded at the start of a program.

This is different from debugging an ordinary executable. In such case, after gdb started, the loader has already done its job for the executable and all associated linked shared libraries, thus you can set break point at once.

PengZheng commented 6 months ago

I changed my mind and thought about it from a different angle, that the problem might not be completely unrelated to Celix.

A first-time user may indeed set a breakpoint and be surprised to find that the debugger does not know where to set the break point (and thus leaves it pending). It might be helpful to beginners if there was a mention in the documentation of how to set up breakpoints for a bundle.

tonychen0924 commented 6 months ago

My test case link: https://github.com/tonychen0924/CelixTest/tree/main/unitDemo

"CtrlConsumer.h" can find and set break point successfully , but "plc_main.c" can not ?

tony@LAPTOP-4AFLJE2J:~/git_pro/CelixTest/unitDemo/build/deploy/MyContainer$ gdb ./MyContainer GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1 Copyright (C) 2022 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 "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: https://www.gnu.org/software/gdb/bugs/. 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 ./MyContainer... (gdb) run Starting program: /home/tony/git_pro/CelixTest/unitDemo/build/deploy/MyContainer/MyContainer [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". [New Thread 0x7ffff69d3640 (LWP 10321)] [New Thread 0x7ffff6141640 (LWP 10322)] -> 注册plc service bundle 启动plc service bundle [New Thread 0x7ffff58d0640 (LWP 10323)] create instance address:0x5555555a8740 create CtrlConsumerBundle bundle, consumer address:0x5555555a8740 StartPLC localPCtrl address:0 WARNING: StartPLC Calc service not available! StopPLC localPCtrl address:0 WARNING: Calc service not available! setCtrlthis address:0x5555555a8740 pCtrl address:0x5555555a7420 [2023-12-29T17:04:30] [ info] [celix_framework] [framework_start:492] Celix framework started StartPLC localPCtrl address:0x5555555a7420 startPLC 1==================== 2==================== 3==================== StopPLC localPCtrl address:0x5555555a7420 stopPLC StartPLC localPCtrl address:0x5555555a7420 startPLC 1==================== 2==================== 3==================== StopPLC localPCtrl address:0x5555555a7420 stopPLC -> lb Bundles: ID State Name Group

0 ACTIVE Celix Framework Celix/Framework 1 ACTIVE Apache Celix CXX Shell Celix/Shell

2 ACTIVE Apache Celix Shell TUI Celix/Shell

3 ACTIVE PlcCtrlBundle

4 ACTIVE RteBundle

-> StartPLC localPCtrl address:0x5555555a7420 startPLC 1==================== 2==================== 3==================== StopPLC localPCtrl address:0x5555555a7420 stopPLC -> quitStartPLC localPCtrl address:0x5555555a7420 startPLC 1==================== 2==================== 3==================== StopPLC localPCtrl address:0x5555555a7420 stopPLC -> quit Quitting framework [New Thread 0x7ffff50cf640 (LWP 10330)] -> setCtrlthis address:0x5555555a8740 pCtrl address:0 [Thread 0x7ffff58d0640 (LWP 10323) exited] [Thread 0x7ffff6141640 (LWP 10322) exited] [Thread 0x7ffff50cf640 (LWP 10330) exited] [Thread 0x7ffff69d3640 (LWP 10321) exited] [Inferior 1 (process 10315) exited normally] (gdb) b CtrlConsumer.h:41 Breakpoint 1 at 0x7ffff58dc3c4: file /home/tony/git_pro/CelixTest/unitDemo/rte/include/CtrlConsumer.h, line 41. (gdb) b plc_main.c:8 No source file named plc_main.c. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 2 (plc_main.c:8) pending. (gdb)

PengZheng commented 6 months ago

"CtrlConsumer.h" can find and set break point successfully , but "plc_main.c" can not ?

Of course you can't. I saw no usage of plc_main.h in the bundle. If none of its interfaces are used, why bother including it at all?

//Ctrl bundle服务提供者和使用者

#include "celix/BundleActivator.h"
#include "CtrlImpl.h"
extern "C"
{
    #include "plc_main.h"
}

class PlcCtrlBundle
{
public:

    //构造函数,初始化成员变量registration
    explicit PlcCtrlBundle(std::shared_ptr<celix::BundleContext> ctx) :
        registration{createPlcService(ctx)}
    {
        std::cout << "启动plc service bundle" << std::endl;
    }

private:
    static std::shared_ptr<celix::ServiceRegistration> createPlcService(std::shared_ptr<celix::BundleContext>& ctx)
    {
        //绑定,赋值
        int seed = 42;
        std::cout << "注册plc service bundle" << std::endl;
        //注册服务
        return ctx->registerService<ACEPHERE_RUNTIME::ICtrl>(std::make_shared<ACEPHERE_RUNTIME::CtrlImpl>(seed))
                .addProperty("seed", seed)
                .build();
    }

    //作为服务端
    const std::shared_ptr<celix::ServiceRegistration> registration;
};

CELIX_GEN_CXX_BUNDLE_ACTIVATOR(PlcCtrlBundle)
tonychen0924 commented 6 months ago

But I don't think it has anything to do with debugger plc_main.c . startPLC of plc_mian.c has been call and print in terminal , but also prompt: void startPLC(int a, int b) { printf("%s\n", __func__); printf("1====================\n"); printf("2====================\n"); printf("3====================\n"); } (gdb) b plc_main.c:8 No source file named plc_main.c. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 2 (plc_main.c:8) pending.

PengZheng commented 6 months ago

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

You only add -g to C++ not to C.

If you follow my advice earlier, then all C and C++ will have -g. If you try the above b startPLC method, you will found that plc_main.c has no debugging information included.

It turns out to be an RTFM issue, totally unrelated to Celix. Sigh. Please pick up a book on CMake and have a good read. This way you will save lots of time for yourself and others.

tonychen0924 commented 6 months ago

I mistakenly thought that just adding C++was enough . Because only the C++compilation options were set during compilation