Author Topic: new idea: ship the debug symbols in a separate file when we distribute C::B  (Read 1953 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5931
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
debugging - How to generate gcc debug symbol outside the build target? - Stack Overflow

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!
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Pecan

  • Plugin developer
  • Lives here!
  • ****
  • Posts: 2790
debugging - How to generate gcc debug symbol outside the build target? - Stack Overflow

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.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5931
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5931
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
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

and

Search for debug symbols in .debug folder Issue #14 jrfonseca/drmingw

I will do a simple test project first.  :)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5931
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
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.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5931
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
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.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5931
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
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.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.