How to get line number at runtime

后端 未结 5 1408
误落风尘
误落风尘 2020-12-03 09:16

is it possible to get source line number at runtime in Delphi? I know JCL debug, but I want to avoid to use it. Also Assert is not exactly what I want. I would like to get s

5条回答
  •  一整个雨季
    2020-12-03 09:33

    For our logging and exception tracing classes, we made a .map parser and reader.

    A .map can be parsed into a binary compressed version (.mab proprietary format), which is much smaller than the original .map. For instance, a 900 KB .map file is compressed into a 70 KB .mab file - this is a much higher compression than zip.

    This .mab content can be appended to the .exe, without any difference at execution, or for the end-user.

    Then you can use our logging classes, or directly the .map/.mab reader class, TSynMapFile.

    You have the following methods at hand:

      /// retrieve a .map file content, to be used e.g. with TSynLog to provide
      // additional debugging information
      // - original .map content can be saved as .mab file in a more optimized format
      TSynMapFile = class   
      public
        /// get the available debugging information
        // - will first search for a .map file in the .exe directory: if found,
        // will be read to retrieve all necessary debugging information - a .mab
        // file will be also created in the same directory (if MabCreate is TRUE)
        // - if .map is not not available, will search for the .mab file in the
        // .exe directory
        // - if no .mab is available, will search for a .mab appended to the exe 
        // - if nothing is available, will log as hexadecimal pointers, without
        // debugging information
        // - if aExeName is not specified, will use the current process executable
        constructor Create(const aExeName: TFileName=''; MabCreate: boolean=true);
        /// save all debugging information in the .mab custom binary format
        // - if no file name is specified, it will be saved as ExeName.mab
        // - this file content can be appended to the executable via SaveToExe method
        // - this function returns the created file name
        function SaveToFile(const aFileName: TFileName=''): TFileName;
        /// save all debugging informat in our custom binary format
        procedure SaveToStream(aStream: TStream);
        /// append all debugging information to an executable
        // - the executable name must be specified, because it's impossible to
        // write to the executable of a running process
        procedure SaveToExe(const aExeName: TFileName);
        /// add some debugging information according to the specified memory address
        // - will create a global TSynMapFile instance for the current process, if
        // necessary
        // - if no debugging information is available (.map or .mab), will write
        // the address as hexadecimal
        class procedure Log(W: TTextWriter; Addr: PtrUInt);
        /// retrieve a symbol according to an absolute code address
        function FindSymbol(aAddr: cardinal): integer;
        /// retrieve an unit and source line, according to an absolute code address
        function FindUnit(aAddr: cardinal; out LineNumber: integer): integer;
        /// return the symbol location according to the supplied absolute address
        // - i.e. unit name, symbol name and line number (if any), as plain text
        // - returns '' if no match found
        function FindLocation(aAddr: Cardinal): RawUTF8;
        /// all symbols associated to the executable
        property Symbols: TSynMapSymbolDynArray read fSymbol;
        /// all units, including line numbers, associated to the executable
        property Units: TSynMapUnitDynArray read fUnit;
      published
        /// the associated file name
        property FileName: TFileName read fMapFile;
        /// equals true if a .map or .mab debugging information has been loaded
        property HasDebugInfo: boolean read fHasDebugInfo;
      end;
    

    Thanks to this class, in just one unit, you'll have all the source code line of any location.

    Open source, and working with Delphi 5 up to XE (note that the .map format changed a little bit from old to newer versions - our class try to handle it).

提交回复
热议问题