Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => Topic started by: ollydbg on February 14, 2024, 03:46:41 am

Title: new idea: ship the debug symbols in a separate file when we distribute C::B
Post by: ollydbg on February 14, 2024, 03:46:41 am
debugging - How to generate gcc debug symbol outside the build target? - Stack Overflow (https://stackoverflow.com/questions/866721/how-to-generate-gcc-debug-symbol-outside-the-build-target)

I see this link, and if we can catch call stack if we supply separate files. Any ideas?

Thanks.

BTW: to everyone, Happy Chinese New Year and Happy Loong 🐲 Year!
Title: Re: new idea: ship the debug symbols in a separate file when we distribute C::B
Post by: Pecan on February 14, 2024, 07:13:43 am
debugging - How to generate gcc debug symbol outside the build target? - Stack Overflow (https://stackoverflow.com/questions/866721/how-to-generate-gcc-debug-symbol-outside-the-build-target)

I see this link, and if we can catch call stack if we supply separate files. Any ideas?

Thanks.

BTW: to everyone, Happy Chinese New Year and Happy Loong 🐲 Year!

Wow !!
If we could distribute the debug symbols and be able to ask a user to: "Thanks for the crash report, could you rerun the problem with the debug symbols ..." etc. we could solve so many more problems. Especially in the on-going battle with CodeCompletion crashes that we have such a devil of a time re-creating in our local enviroment.
Title: Re: new idea: ship the debug symbols in a separate file when we distribute C::B
Post by: ollydbg on February 14, 2024, 09:09:36 am
Yes, I think they will help use to catch the crashes easily.

Our crash reporter is using

jrfonseca/drmingw: Postmortem debugging tools for MinGW. (https://github.com/jrfonseca/drmingw)

And I see the drmingw use the davea42/libdwarf-code: Contains source for libdwarf, a library for reading DWARF2 and later DWARF. Contains source to create dwarfdump, a program which prints DWARF2 and later DWARF in readable format. Has a very limited DWARF writer set of functions in libdwarfp (producer library). Builds using GNU configure, meson, or cmake. (https://github.com/davea42/libdwarf-code) to read the symbols.

So, I will first try to find whether those tools support separate debug files.
Title: Re: new idea: ship the debug symbols in a separate file when we distribute C::B
Post by: ollydbg on February 14, 2024, 09:16:17 am
A simple search in the drmingw site reveals that this feature is already supported. That's nice!

See:

Allow reading debug symbols from external files Issue #11 jrfonseca/drmingw (https://github.com/jrfonseca/drmingw/issues/11)

and

Search for debug symbols in .debug folder Issue #14 jrfonseca/drmingw (https://github.com/jrfonseca/drmingw/issues/14)

I will do a simple test project first.  :)
Title: Re: new idea: ship the debug symbols in a separate file when we distribute C::B
Post by: ollydbg on February 14, 2024, 10:30:59 am
A simple test shows that the separate debug symbol files of a exe file works correctly, drmingw can correctly record the RPT file.

For testing, I use the msys2/mingw64's gcc

https://packages.msys2.org/package/mingw-w64-x86_64-drmingw?repo=mingw64

And here is the test code: https://github.com/jrfonseca/drmingw/blob/master/sample/sample.cpp

When I generate a file named "test-drmingw.exe" under the "bin/Debug" folder, I have to run the following command to separate 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

The above operation is mainly followed by the answer in the post here: https://stackoverflow.com/a/18487233/154911

Then I run the exe file, and I see the test-drmingw.RPT shows the correct debug line information.

I will try to test whether a dll file crash works.
Title: Re: new idea: ship the debug symbols in a separate file when we distribute C::B
Post by: ollydbg on February 14, 2024, 12:16:00 pm
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__



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
}


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;
}


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

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.
Title: Re: new idea: ship the debug symbols in a separate file when we distribute C::B
Post by: ollydbg on February 14, 2024, 12:42:16 pm
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;
}

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

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.