Search code examples
c++multithreadingfunctionlogging

Logging function calls to a library


I'm working on a multi-threaded, complex C++ program that constantly calls into an external library for some functionalities. I'm tracing a bug that occurs very randomly and am trying to figure out if the library calls have anything to do with it.

Is there a way to log all functions to the library without having to alter source code? All the function calls to the library have a specific prefix to it.

Using VSCode if it helps.


Solution

  • One of, or a combination of, the below, may prove useful in ascertaining the information you require:

    1. Using IDA Pro - Static Disassembly

      You will need to identify a place in code to start. Open the container of your starting point for disassembly: if the starting point is within an executable, you would disassemble the executable, if it is within a DLL, you would disassemble the DLL. There will be some functions that IDA has knowledge of, i.e., Standard library functionality, and as IDA knows the signature of these functions, the software can identify them to you in the disassembled form, however other functions will not have meaningful names. You can trace through all of the calls made from the starting point - check online for some tutorials using IDA.

    2. OllyDbg - Dynamic Disassembly

      OllyDbg is a useful debugging and patching tool developed by one of my peers from the old game modding scene.

      Unlike with IDA Pro, you would follow your route through the code by the application being run and the debugger being attached. As you step through the code, you will see the functions called. Again, you would do well to find online tutorials to learn how to use this tool.

    3. Class Inheritance

      This may or may not be applicable - depending on your use-case - but it is a method of intercepting a class' function call.

      If you wish to determine the call of a specific function defined within a class, you can derive your own class from the base class, define the function - with a matching signature - within the derived class, instantiate your class instead of the base class, and when the specified function is called it should call your function instead of the base class' version.

      An example of me doing this as a cringe-worthy work around within QT, when a charting feature would not work based on the chart type:

      QtCharts::QAbstractAxis::AxisType TTCategoryAxis::type(void) const
      {
          HMODULE hMod = GetModuleHandleA("Qt5Chartsd.dll");
          void *returnAddress = _ReturnAddress();
          qint64 result = ((qint64)returnAddress) - (qint64)(hMod);
      
          if(result == UPDATE_GEO_OFFSET) // If the callee is the function we wish to trick, return a type of QDateTimeAxis
              return QAbstractAxis::AxisTypeDateTime;
      
          // otherwise return QCategoryAxis::type();
          return QCategoryAxis::type();
      }
      
    4. Similar to #3, you can write a wrapper library containing the same symbols, and just like #3 call the original functionality.

    Another tool that may be useful is the objdump tool from bintools.

    This useful tool allows to you dump all external symbol references, but just because a function may be referenced does not mean it is utilised.

    It would likely be much easier to run over the actual problem in a post here, enabling us to provide a possible method of working out the issue with you, if the issue is not already obvious to one of the community.