Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 04/04/21 in all areas

  1. Anders Melander

    MAP2PDB - Profiling with VTune

    @Attila Kovacs I found and fixed the problem; The size of the MSF Directory stream had grown beyond 1 block and my implementation of the MSF Directory Index assumed that a one block directory would be enough (who needs more than 640K anyway?) so I only wrote one block pointer. A module stream is created for each unit so if there are many units in a project there will be many stream and thus many entries in the directory. In your case there were 1775 streams in total. @David Heffernan I've also implemented support for PE32+ (64 bit). I guess I'm procrastinating to avoid handling the 16Mb limit New version uploaded.
  2. Anders Melander

    MAP2PDB - Profiling with VTune

    It took me a bit longer than expected to get here but I believe I've finally reached the goal. The following shows VTune profiling a Delphi application, with symbol, line number and source code resolution: Download Get the source here: https://bitbucket.org/anders_melander/map2pdb/ And a precompiled exe here: https://bitbucket.org/anders_melander/map2pdb/downloads/ The source has only been tested with Delphi 10.3 - uses inline vars so it will not compile with older versions. Usage map2pdb - Copyright (c) 2021 Anders Melander Version 2.0 Parses the map file produced by Delphi and writes a PDB file. Usage: map2pdb [options] <map-filename> Options: -v Verbose output -pdb[:<output-filename>] Writes a PDB (default) -yaml[:<output-filename>] Writes an YAML file that can be used with llvm-pdbutil -bind[:<exe-filename>] Patches a Delphi compiled exe file to include a reference to the pdb file -test Works on test data. Ignores the input file Example: Configure your project linker options to output a Detailed map file. Compile the project. Execute map2pdb <map-filename> -bind Profile the application with VTune (or whatever) Known issues The -bind switch must occur after the filename contrary to the usage instructions. PDB files larger than 16Mb are not valid. This is currently by design. 64-bit PE files are not yet supported by the -bind option. As should be evident I decided not to go the DWARF route after all. After using a few days to read the DWARF specification and examine the FPC source I decided that it would be easier to leverage the PDB knowledge I had already acquired. Not that this has been easy. Even though I've been able to use the LLVM PDB implementation and Microsoft's PDB source as a reference LLVM's implementation is incomplete and buggy and the LLVM source is "modern C++" which means that it's close to unreadable in places. Microsoft's source, while written in clean C and guaranteed to be correct, doesn't compile and is poorly commented. Luckily it was nothing a few all-nighters with a disassembler and a hex editor couldn't solve. Enjoy!
  3. Vincent Parrett

    MAP2PDB - Profiling with VTune

    It wasn't that, and I probably did forget the bind switch before I sent it to you, however with the new version.... we have lift off! Awesome work! E:\map2pdb>map2pdb.exe I:\FBAT_HG9\Output\FB9\FinalBuilder9.map -v -bind:I:\FBAT_HG9\Output\FB9\FinalBuilder9.exe map2pdb - Copyright (c) 2021 Anders Melander Version 2.0 Constructed a new PDB GUID: {CE1E6D08-67E6-4B5B-B42A-3FC719254F1E} Output filename not specified. Defaulting to FinalBuilder9.pdb Reading MAP file - Segments Warning: [ 8] Empty segment: .pdata [0006:00400000] - Modules - Symbols Warning: [20671] Failed to resolve symbol to module: [0005:00000608] SysInit.TlsLast Warning: [20673] Failed to resolve symbol to module: [0004:FF77A000] SysInit.__ImageBase - Line numbers Warning: [71563] Line number with zero offset ignored. Module:VSoft.IDE.Types, Segment:0001, Source:VSoft.IDE.Types.pas, Line:49 Warning: [71567] Line number with zero offset ignored. Module:VSoft.IDE.Interfaces, Segment:0001, Source:VSoft.IDE.Interfaces.pas, Line:328 Warning: [75481] Line number with zero offset ignored. Module:LMDRTLConst, Segment:0001, Source:LMDRTLConst.pas, Line:213 Warning: [75621] Line number with zero offset ignored. Module:intfLMDBase, Segment:0001, Source:intfLMDBase.pas, Line:44 Warning: [76980] Line number with zero offset ignored. Module:LMDDckCst, Segment:0001, Source:LMDDckCst.pas, Line:29 Warning: [79649] Line number with zero offset ignored. Module:VSoft.IDE.ActionListInterfaces, Segment:0001, Source:VSoft.IDE.ActionListInterfaces.pas, Line:136 Warning: [90056] Line number with zero offset ignored. Module:SynEditStrConst, Segment:0001, Source:SynEditStrConst.pas, Line:577 Warning: [98436] Line number with zero offset ignored. Module:VSoft.IDE.WizardManagerService, Segment:0001, Source:VSoft.IDE.WizardManagerService.pas, Line:61 Warning: [99799] Line number with zero offset ignored. Module:dwTaskbarList, Segment:0001, Source:dwTaskbarList.pas, Line:213 Warning: [103835] Line number with zero offset ignored. Module:RestException, Segment:0001, Source:RestException.pas, Line:26 Warning: [105461] Line number with zero offset ignored. Module:VSoft.Shared.UXLControlIntf, Segment:0001, Source:VSoft.Shared.UXLControlIntf.pas, Line:60 Warning: [107033] Line number with zero offset ignored. Module:VSoft.IDE.MS.ActionCollection.Interfaces, Segment:0001, Source:VSoft.IDE.MS.ActionCollection.Interfaces.pas, Line:1085 Constructing PDB file - Collecting source file names - Module streams - Strings stream - PDB Info stream - TPI stream - Symbols stream - DBI stream - IPI stream - Finalizing PDB file Patching PE file - PE32 image (32-bit) - PDB file name has been stored in debug data. - Header checksum has been cleared. - PE file has been updated. I was also able to create a pdb for the package E:\map2pdb>map2pdb.exe I:\FBAT_HG9\Output\FB9\VSoft.Core.map -bind:I:\FBAT_HG9\Output\FB9\VSoft.Core.bpl -v map2pdb - Copyright (c) 2021 Anders Melander Version 2.0 Constructed a new PDB GUID: {76323C0F-0787-44F8-BC72-2B6ACC9CBF82} Output filename not specified. Defaulting to VSoft.Core.pdb Reading MAP file - Segments Warning: [ 7] Empty segment: .tls [0005:00000000] Warning: [ 8] Empty segment: .pdata [0006:00400000] - Modules Warning: [ 1682] Module exceed segment bounds - ignored: OtlCommon.Utils [0005:00000000+256] - Symbols Warning: [ 6403] Failed to resolve symbol to module: [0005:00000000] OtlCommon.Utils.LastThreadName Warning: [ 8705] Failed to resolve symbol to module: [0005:00000100] SysInit.TlsLast Warning: [ 8709] Failed to resolve symbol to module: [0004:FFBF8000] SysInit.__ImageBase - Line numbers Warning: [64147] Line number offset out of range for module. Offset:003DAEEF, Module:.VSoft.Core [003DAEF0 - 003E5738] Constructing PDB file - Collecting source file names - Module streams - Strings stream - PDB Info stream - TPI stream - Symbols stream - DBI stream - IPI stream - Finalizing PDB file Patching PE file - PE32 image (32-bit) - PDB file name has been stored in debug data. - Header checksum has been cleared. - PE file has been updated. Now to hook it into every project in the group and see how it goes 😃 Thanks again for this awesome effort.. my only question now is, if you can do this in your spare time, why TF can't embarcadero do it 🙄
  4. Attila Kovacs

    MAP2PDB - Profiling with VTune

    yes yes yes yes yes yes yes! finally we can debug too! @Anders Melander it works! \o/
  5. Dalija Prasnikar

    caFree & ,Free??

    And that is exactly the situation OP has encountered here. I guess you missed that part.
  6. Dalija Prasnikar

    caFree & ,Free??

    No. It is not OK. You are trying to release the form twice. Once explicitly by calling Free and once by setting on close Action to caFree. This may work under some circumstances, like @balabuev mentioned caFree triggers posting CM_RELEASE message to the form window handle. If there is no code that will pump the message queue (like Application.ProcessMessages) between the time OnFormClose is called and your explicit call to Free, then calling Free will actually destroy the form and along with it its window handle and message posted to that handle will be discarded because window no longer exists. However, if CM_RELEASE message is processed and handled before your explicit Free call, form will already be destroyed at the point you call Free and hence the error you are seeing (presumably from EurekaLog) Because you have added some other code in between that is calling Application.ProcessMessages. You have to choose one option. Either you will use caFree or you will use Free. Using both and hoping for the best is not good option even if it works, because it can be easily broken, which you now have first hand experience. If you need to retrieve some value from the form after it is closed, then you shouldn't use caFree anyway because you may access dead form - again depending on the other surrounding code. Another reason to explicitly Free form is that this makes memory management more obvious. You create form, do something with it, and then you release it.
  7. Anders Melander

    MAP2PDB - Profiling with VTune

    I don't think there's enough information in the map file to solve that problem properly but I'll investigate it some more when I've gotten these other things out of the way.
  8. Anders Melander

    MAP2PDB - Profiling with VTune

    Yes - and yes
  9. Anders Melander

    MAP2PDB - Profiling with VTune

    The problem with your map file was just that my validation was a bit too aggressive. I've now turned some of the errors into warnings. New version uploaded. One of the problems was that I discarded zero size segments. E.g. the TLS segment: 0005:00000000 00000000H .tls TLS which meant that later on when a module or symbol tried to resolve segment #5 that turned into an error. Detailed map of segments 0005:00000000 00000100 C=TLS S=.tls G=(none) M=OtlCommon.Utils ACBP=A9 Address Publics by Name 0005:00000000 OtlCommon.Utils.LastThreadName 0005:00000100 SysInit.TlsLast I'm not not really sure of how I should handle these out of bounds situations. Right now I just warn about them and then ignore the module/symbol/line. I think you just forgot the -bind switch. Your project3.exe did not contain a reference to project3.pdb. After I run map2pdb -bind project3,map I got VTune to resolve with your exe. You're probably hitting the 16Mb limit, I'm now outputting a warning so we're aware of it when it happens. I was planning on adding support for PE32+ (64-bit) next but I guess solving the MSF/16Mb problem is more important. I can't really use it myself for anything serious until that's done.
  10. balabuev

    caFree & ,Free??

    As recently has been mentioned in another thread, it's only safe if the code inside try/finally do not occasionally (or indirectly) call Application.ProcessMessages after ShowModal: MyForm := TMyForm.Create(...); try MyForm.ShowModal; Application.ProcessMessages; // Or SomeAnotherForm.ShowModal, etc. finally MyForm.Free; end; In this case the form may be freed via CM_RELEASE, and then - freed the second time via the code in finally block.
  11. David Schwartz

    Learning Delphi

    Right out of school ... it will depend what they were exposed to in school. They probably understand OOP and OOD, but may not have much experience with strongly-typed languages like C/C++ and Pascal/Delphi. To me, after 40 years, most imperative languages all look the same, except for added things for stuff like vectors, parallelism, and more esoteric stuff that all tend to be language-specific. The latest feature that most languages are adopting is the use of "attributes" on classes and class members. I don't know how Delphi's stack up against any others, but it may be worth discussing. Other than that, what I'd call the "dynamics" are going to be a big part of what can hang them up. For instance, Delphi has added some interesting features to the language like for...in that make using various kinds of containers a lot easier. But there are things missing from Delphi that make it impossible to use some of these newer features at times. For...in is great unless you need to refer to the index or position of the selected item in the list, for example. The lack of a trinary operator means there are lots of if...then...else statements that could be collapsed into a much simpler trinary expression. There's the IfThen method, but it evaluates both arguments before choosing one, which makes it useless when trying to avoid referencing null pointers. Most contemporary languages accomodate both of these things today, so it might seem confusing in that respect. (Delphi may support it in an upcoming release as part of NULL expressions, but a trinary operator could have been introduced in the languge way back that simplified it forever.) The RTL has been extended using class helpers to mirror a lot of stuff commonly found in C# today. Class helpers seem like a hack to me, but they do let you introduce new methods into a class without having to either modify the class itself or subclass it. Unfortunately, they're not inheritable, which seems really strange to me (and probalby newcomers as well). Most contemporary languages also support case statements that take strings as discriminant variables, but not Delphi. This gives rise to maybe a dozen different ways people work-around this missing language feature that's only missing for little more than "religious" reasons. Initialization of arrays, lists, and objects in Delphi is something that isn't often consistently applied within and across projects, so make some clear recommendations. (Good Idea for a Coding Style document.) In particular, if you have a list of Enums, there's a common practice of prefixing them with a couple of letters so you know what class they belong to. This prevents simple use of RTTI to get a string representation of their name to display at run-time. So you need a second array of names and a lookup function for that purpose, although I've seen slightly more elegant ways of doing it that escape my mind at the moment. (To me this sort of variable-name-to-string-name mapping should be a fundamental language feature of every programming language ever written. In practice, few if any offer anything at all.) This stuff can be really confusing to people familiar with what other contemporary languages offer in their place. So I'd say give them a lot of "bread-and-butter" type code to write and do a lot of code reviews to suggest alternate ways of expressing things to expand their understanding of the language and RTL. If you're having them build UI-based apps, try to instill some good coding practices, like avoiding putting logic into Event handler methods. It's so easy to do, right? For example, the presence of an Add and Edit button on a form might lead to two almost identical methods, one of which might initialize stuff from one set of vars while the other will initialize with constants. And to allow a "Cancel" button, you probably need to track whether you're in Add or Edit mode. (Forms that use DB-aware controls can handle this directly.) One thing that I personally find quite ridiculous is the fact that most Delphi programmers don't treat interfacing with forms the same way as other objects. For reasons going back to Delphi 1, Delphi allows the programmer to reach directly into forms and fiddle with local variables and even fields from methods inside of the client forms (which are bona fide objects!) using with them, where nobody in their right mind would do the same thing with normal objects. I see very few Delphi apps that do this consistently and what I'd say is "correctly". Again, I think this gets into more of a "religious" debate, but if there's not a lot of consistency in how it's done in your projects, a new programmer is going to naturally ask "WHY?" and be rightfully confused over something that really has no excuse other than the programmers were lazy. Finally, keep on the lookout for use / abuse of global variables. As far as learning the language itself goes, I'd say any old Delphi book from D4 onwards can be used as a guide for most things, except the screenshots of the IDE. Newer versions have more methods in older (ie, "classic") objects than are found in older books, but what's there is pretty much all still 100% valid. I'd also be tempted to give them some exercises to learn all they can about TStringList. It has always been one of the objects in the RTL that I've used the most over time, and they seem to keep adding new functions to it with every Delphi release. This is what comes to mind in a few minutes. There's probably a lot more.
  12. Selecting text in an edit control is for sure a use case where this is needed.
  13. I don't think this is true. TEdit is the Win32 EDIT control. What are you doing with strings that need to know what you are asking about? What's your usage scenario?
  14. It appears that ICU is the way to go. ICU is now bunded in Windows, .NET 5 is based on ICU, also android Unicode and internationalization support | Android Developers and iOS ICU usage in Swift - Development / Standard Library - Swift Forums
  15. Attila Kovacs

    Email Tampering

    Depending on the MTA settings it could keep and try to pass it to the MX for even 5+ days. Date could also be in the future and not only in the past. Spamfilters are ranking emails with points, you could adopt this method. Also, you could look up spamassassin's and policyd-weight's rules to find out more.
  16. Vandrovnik

    Email Tampering

    E-mail clients often are able to work in offline mode and then send/receive e-mails when connection is available. I believe that in this case "Date" and first "Received" can differ significantly.
  17. haentschman

    caFree & ,Free??

    Hi... ...No. It contains "with". "with" is like 90s... Why use many developers the "with"...old school? Everybody knows by now that there can be problems with this...TRect (example) or no resolution of variables during debugging.
×