File indexing completed on 2024-03-24 17:01:21

0001 /******************************************************************
0002  *
0003  * kdbgwin - Helper application for DrKonqi
0004  *
0005  * This file is part of the KDE project
0006  *
0007  * SPDX-FileCopyrightText: 2010 Ilie Halip <lupuroshu@gmail.com>
0008  *
0009  * SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0010  *****************************************************************/
0011 
0012 #pragma once
0013 
0014 #include "common.h"
0015 #include "kdbgwin_process.h"
0016 
0017 #include <QObject>
0018 
0019 const static char *BACKTRACE_FORMAT = "%1!%2() [%3 @ %4] at 0x%5";
0020 // module.dll!KClass::function() [c:\file.cpp @ 10] at 0x0001000
0021 
0022 const static char *DEFAULT_MODULE = "[unknown]";
0023 const static char *DEFAULT_FUNC = "[unknown]";
0024 const static char *DEFAULT_FILE = "[unknown]";
0025 const static int DEFAULT_LINE = -1;
0026 
0027 /**
0028  * \brief Base generator class
0029  *
0030  * This class gives the definition of a backtrace generator. There are 2 subclasses: one for
0031  * MSVC and one for MinGW. The reason why implementation differs is the fact that executables
0032  * use different debugging formats: PDBs (for MSVC) and Dwarf-2/Stabs and possibly more I don't
0033  * know too much about for MinGW, which are embedded in the executable itself.
0034  */
0035 class AbstractBTGenerator : public QObject
0036 {
0037     Q_OBJECT
0038 protected:
0039     /// A Process instance, corresponding to the process for which we generate the backtrace
0040     Process m_process;
0041 
0042     /// The current stack frame. It is kept as a member
0043     STACKFRAME64 m_currentFrame;
0044 
0045     /// The definition of a map of symbols
0046     typedef QMap<QString, bool> TSymbolsMap;
0047     /// A map of symbols (the full path to the module, and a bool which specifies if
0048     /// symbols were loaded for it)
0049     TSymbolsMap m_symbolsMap;
0050 
0051 public:
0052     /// Constructor
0053     AbstractBTGenerator(const Process &process);
0054     virtual ~AbstractBTGenerator();
0055 
0056     /// Abstract virtual: Initialize this generator
0057     virtual bool Init() = 0;
0058 
0059     /// Abstract virtual: Uninitialize this generator
0060     virtual void UnInit() = 0;
0061 
0062     /// Start generating the backtrace
0063     virtual void Run(HANDLE hTread, bool bFaultingThread);
0064 
0065     /// This method acts like a callback and will be called when the stack frame changed
0066     virtual void FrameChanged() = 0;
0067 
0068     /// Abstract virtual: get current module name
0069     /// @return the name of the current module (eg: kdecore.dll)
0070     virtual QString GetModuleName();
0071 
0072     /// Abstract virtual: get current module path
0073     /// @return the full path to the current module (eg: N:\\kde\\bin\\kdecore.dll)
0074     virtual QString GetModulePath();
0075 
0076     /// Abstract virtual: get current function/method name. The name is undecorated internally by this method.
0077     /// @return the current function or method (eg: KCmdLineArgs::args)
0078     virtual QString GetFunctionName() = 0;
0079 
0080     /// Abstract virtual: get the full path to the current file
0081     /// @return the path to the file (eg: N:\\kde\\svn\\KDE\\trunk\\kdelibs\\kcmdlineargs\\kcmdlineargs.cpp)
0082     virtual QString GetFile() = 0;
0083 
0084     /// Abstract virtual: get current line
0085     /// @return the current line in the file
0086     virtual int GetLine() = 0;
0087 
0088     /// Checks if symbols are loaded for the specified module
0089     /// @return true if symbols are loaded
0090     virtual bool IsSymbolLoaded(const QString &module);
0091 
0092     /// Tries to load symbols for all loaded modules
0093     virtual void LoadSymbols();
0094 
0095     /// Tries to load a symbol file for a module loaded at dwBaseAddr
0096     virtual void LoadSymbol(const QString &module, DWORD64 dwBaseAddr) = 0;
0097 Q_SIGNALS:
0098     /// This will be emitted whenever the generator wishes to output information. It can either be
0099     /// module information (in the form: "Loaded C:\path\to.dll (symbols loaded)", a stack frame line,
0100     /// or newlines
0101     void DebugLine(const QString &);
0102 
0103     /// This signal is emitted when a module is loaded, and its symbols are missing. This is
0104     /// caught by the PackageSuggester
0105     void MissingSymbol(const QString &);
0106 
0107     /// Will be emitted when the generation finishes
0108     void Finished();
0109 };