Developer forums (C::B DEVELOPMENT STRICTLY!) > Development

new idea: ship the debug symbols in a separate file when we distribute C::B

<< < (2/2)

ollydbg:
Here is the dll test, it works also OK when I separate the debug symbols in the dll.

dll header files:


--- Code: ---#ifndef __DLL_H__
#define __DLL_H__

#include <windows.h>

/*  To use this exported function of dll, include this header
 *  in your project.
 */

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif


#ifdef __cplusplus
extern "C"
{
#endif

void DLL_EXPORT SomeFunction(const LPCSTR sometext);

#ifdef __cplusplus
}
#endif

#endif // __DLL_H__


--- End code ---


dll.cpp file:


--- Code: ---#include "dll.h"

// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
    MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
    int a = 0;
    int b = 5;
    int c = b/a;
}

extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            break;

        case DLL_PROCESS_DETACH:
            // detach from process
            break;

        case DLL_THREAD_ATTACH:
            // attach to thread
            break;

        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}


--- End code ---

Now, the exe (main.cpp) file needs to adjust like below:


--- Code: ---
/* Public Domain.
 *
 * A sample C++ program for Dr.MinGW.
 */

#include <stdio.h>
#include <stdlib.h>

#include "exchndl.h"

#include "dll.h"

static void Function(int i, double j, const char * pszString) {
    sscanf("12345", "%i", (int *)1);
}

struct Class {
    static void StaticMethod(int i, float j) {
        Function(i * 2, j, "Hello");
    }

    void Method(void) {
        StaticMethod(4, 5.6f);
    }
};

int main() {
    ExcHndlInit();
    Class instance;

    SomeFunction("abc");

    //instance.Method();
    return 0;
}


--- End code ---

The "test-drmingw.exe" and "test-drmingw-dll.dll" were all put in the "bin/Debug" folder, then I run the command below to separate all the debug symbols:


--- Code: ---objcopy --only-keep-debug test-drmingw.exe test-drmingw.debug
strip --strip-debug --strip-unneeded test-drmingw.exe
objcopy --add-gnu-debuglink test-drmingw.debug test-drmingw.exe

objcopy --only-keep-debug test-drmingw-dll.dll test-drmingw-dll.debug
strip --strip-debug --strip-unneeded test-drmingw-dll.dll
objcopy --add-gnu-debuglink test-drmingw-dll.debug test-drmingw-dll.dll

--- End code ---

The next step is: try to load the dll file from a sub folder, such as "bin/Debug/plugin", put the "test-drmingw-dll.dll" and "test-drmingw-dll.debug" in the "plugin" folder.

ollydbg:
OK, the dynamically loading of the dll and calling the function also works.

To do this, I have:

1, change the main.cpp (the code to generate the exe file) like below:


--- Code: ---#include <stdio.h>
#include <stdlib.h>

#include "exchndl.h"

typedef void (*SomeFunctionPtr)(const LPCSTR);

int main() {
    ExcHndlInit();

    HMODULE h = LoadLibrary("plugin/test-drmingw-dll.dll");
    SomeFunctionPtr f = reinterpret_cast<SomeFunctionPtr>(GetProcAddress(h, "SomeFunction"));
    f("abc");

    return 0;
}

--- End code ---

and separate the debug symbol of this exe file by calling:


--- Code: ---objcopy --only-keep-debug test-drmingw.exe test-drmingw.debug
strip --strip-debug --strip-unneeded test-drmingw.exe
objcopy --add-gnu-debuglink test-drmingw.debug test-drmingw.exe

--- End code ---

2, now I move the two files "test-drmingw-dll.dll" and "test-drmingw-dll.debug" to a sub-folder "bin/Debug/plugin".

Since those two files were already debug symbol separated files, I do not need to rebuild the dlls.

3, run the exe file, it will crash inside the dll function call, now see whether the "test-drmingw.RPT" in the root folder (the "bin/Debug" folder).

Yes, it does show the correct call stack with source code lines.

ollydbg:
Hi, I did some test on separating the debug information from the plugin dlls, and it works fine, with the help of LLM AI model, I create a Windows batch file named separate-debug-info.cmd file, it contents are below:


--- Code: ---@echo off
REM Use the directory of this batch file as the target directory.
set "TARGET_DIR=%~dp0"

REM Process all EXE files in the target directory.
for %%F in ("%TARGET_DIR%\*.exe") do (
    echo Processing %%F...
    objcopy --only-keep-debug "%%F" "%%~dpnF.debug"
    strip --strip-debug --strip-unneeded "%%F"
    objcopy --add-gnu-debuglink="%%~dpnF.debug" "%%F"
)

REM Process all DLL files in the target directory.
for %%F in ("%TARGET_DIR%\*.dll") do (
    echo Processing %%F...
    objcopy --only-keep-debug "%%F" "%%~dpnF.debug"
    strip --strip-debug --strip-unneeded "%%F"
    objcopy --add-gnu-debuglink="%%~dpnF.debug" "%%F"
)

echo Done.
pause

--- End code ---

Now, put this .cmd file in the folder: <root>\src\devel32_64\share\CodeBlocks\plugins

And suppose you have the command line tools installed, for me, I have msys2's mingw64, and those tools were already installed.

After running this cmd file, you get such contents:


--- Code: ---# du -b --block-size=1K *
2056    abbreviations.debug
211     abbreviations.dll
4870    astyle.debug
547     astyle.dll
1097    autosave.debug
124     autosave.dll
1822    classwizard.debug
179     classwizard.dll
23896   codecompletion.debug
1619    codecompletion.dll
17193   compiler.debug
1092    compiler.dll
10200   debugger.debug
763     debugger.dll
2171    defaultmimehandler.debug
184     defaultmimehandler.dll
2931    OccurrencesHighlighting.debug
207     OccurrencesHighlighting.dll
1584    openfileslist.debug
133     openfileslist.dll
90669   org
5214    projectsimporter.debug
278     projectsimporter.dll
6434    scriptedwizard.debug
482     scriptedwizard.dll
1       separate-debug-info.cmd
4776    todo.debug
305     todo.dll
770     xpmanifest.debug
51      xpmanifest.dll

--- End code ---

Note the fist column is the filesize in kilobyte unit.

When you run gdb on the debugee C::B, setting breakpoints on the dll source file still works, which means the separating of the debug information work.

Navigation

[0] Message Index

[*] Previous page

Go to full version