debug | evaluate does not know about LCL lazarus / 12-Debugger ---------------------------------------------------------------------- lazer · 2022-10-19 11:36 I'm trying to debug a crash and need to evaluate an expression The evaluate window seems unaware of LCL definitions. Is this expected ? TIA. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 12:01 Open the package LCL (or any other that you need), and ensure in the package options that it is build with dwarf debug info. In many cases this is default (default is "automatic" which often -but not always - is dwarf), but it is not enforced. You can also set this in "configure build lazarus" as " -gw3 " => which is (if you did not change anything) forwarded to lots of packages. Or use "additions and overwrites" (search wiki) ---------------------------------------------------------------------- lazer · 2022-10-19 13:00 Thanks. I set the options to -gw3 , make lazarus-main/components user writable, and Run | Clean up and build  from IDE. It is still shows the same error in Evaluate.  The files in  lazarus- main/components  have not changed. I had to give it access to lazarus-main/lcl/interfaces/backup too , now it seems to be able to compile individual units from IDE. is fpguiwsbuttons.pp what I need for Tspeedbutton ? ---------------------------------------------------------------------- Martin_fr · 2022-10-19 14:55 Ok, something is seriously broken in your setup. I just tested this on Fedora. That definitely works. (That said, you got the closing bracket in the wrong place, but that wouldn't lead to the "not found" error). Just one more idea. Which version of FPC did you use to build your Lazarus? FPC 3.2.2 (the release) has a bug in the optimizer. If you build the IDE with -O2 or higher, then the debugger does not work. So then you need to build Lazarus with -O1 In 3.3.1 this bug is fixed. Not sure about 3.2.3 (fixes branch, IIRC it is fixed there too, but...) Also to be on the save side: Rebuild your IDE with "clean all". There have been reports that every once in a blue moon, a partial rebuild lead to a broken exe. Maybe you can test this on a different PC / virtual machine with a different OS? At the moment its a bit of a wild goose chase / shooting in the dark. All I can do is asking very broad questions, in the hope that some info comes up, that gives some lead towards what is happening. I have several virtual machines, with different Linux versions in 32/64 bit, as well as Windows 10, 7, vista and XP for testing. I do test the debugger with FPC versions starting at 2.6.4 up to the latest git (updated every few month). The automated testcase evaluates over 10.000 watches. (Just to say, some of the older setups are tested only once or twice per year, it takes a long time to run through all of this) Whatever happens to you, it is not the normal/expected experience. It may still be a bug in FpDebug (but as I said it could be the linker, or anything else), but to fix it (be that in FpDebug, in FPC, or by some other mean) I need some idea what is different on your setup. ---------------------------------------------------------------------- lazer · 2022-10-19 15:03 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     textPanels:array[0..2]of ^TPanel;  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   textPanels[0]:=@spellwin.textPanel1;  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   textPanel0.tag:=longint(@speedBtn0); Quote (That said, you got the closing bracket in the wrong place, but that wouldn't lead to the "not found" error). So this ref looks legit: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Tspeedbutton(textPanels[i]^.tag) If I had that wrong it would probably fail to compile. That's  a side issue I was just showing the lack of eval.  The question is, why does it not know about TspeedButton at all ? Something is wrong , maybe something in my code which is confusing the debugger or the same problem which causes objdump to barf. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 15:11 Oh, ok => you got the speedbutton stored in the Tag. I thought you have it in the array entry. Off topic, TPanel (as every instance of a class) has a hidden internal pointer. So for the variable "aPanel: TPanel" you get "sizeOf(aPanel) = sizeOf(Pointer)" Hence you may not need the extra pointer "^TPanel" ---------------------------------------------------------------------- lazer · 2022-10-19 15:14 Ah , so you are saying that if I put an array of TPanel, it will not be allocating actual Tpanels ?  That would be less brain juggling Thanks. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 15:15 Quote from: lazer on October 19, 2022, 05:03:51 pmSomething is wrong , maybe something in my code which is confusing the debugger or the same problem which causes objdump to barf. This is one possible lead. It is possible that some bug in the debug info prevents it from being read beyond some point => meaning that a lot of symbols and variables would not be found. As I said, if objdump has still produced output, it would be great if you could send it to me. And ideally also send the executable that causes this. I do not need the source. But the files do (as debug info does) contain names of your functions and variables.... I will handle any data received as confidential, and delete it once I debugged it. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 15:22 Quote from: lazer on October 19, 2022, 05:14:03 pmAh , so you are saying that if I put and array of TPanel, it will not be allocating actual Tpanels ?  That would be less brain juggling Thanks. Yep. "class" (TObject and any descendent) are pointers. "type Tfoo = record ... end" and "type Tfoo = object ... end" are NOT pointers. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var a, b: TPanel;  // this allocates space for a pointer (one for each variable)  // for a global variable, this is in the data section  // for a local variable this is on the stackbegin  a := TPanel.Create;  // this allocates memory on the "heap" and "a" will point to that memory  b := a;  // Now a and b point to the same data  b.tag := 123; // this changes the tag for a and b   FreeAndNil(a);  // releases the memory, and sets a:=nil.  // NOTE: Now b is a dangling pointer  if assigned(b) then // this is TRUE    b.tag := 999; // CRASH or data corruption. b points to memory that was freed. So the 999 overwrites whatever other new data is now in that memory block...end; ---------------------------------------------------------------------- lazer · 2022-10-19 15:40 Thanks for pointer on pointers. That makes life simpler. I'm not too happy with sending the dump. Most of it is useless anyway,  it's all the standard LCL stuff before it fails. Here is the tail of the objdump. You will see it encounters an "unknown convention" and that causes it to fail. That may mean something to you. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i <1><25a6>: Abbrev Number: 15 (DW_TAG_reference_type)    <25a7>   DW_AT_type      : <0x258c> <1><25ab>: Abbrev Number: 13 (DW_TAG_typedef)    <25ac>   DW_AT_name        : Char    <25b1>   DW_AT_type        : <0x25b5> <1><25b5>: Abbrev Number: 16 (DW_TAG_base_type)    <25b6>   DW_AT_name        : Char    <25bb>   DW_AT_encoding    : 8  (unsigned char)    <25bc>   DW_AT_byte_size   : 1 <1><25bd>: Abbrev Number: 15 (DW_TAG_reference_type)    <25be>   DW_AT_type        : <0x25ab> <1><25c2>: Abbrev Number: 13 (DW_TAG_typedef)    <25c3>   DW_AT_name        : ShortString    <25cf>   DW_AT_type        : <0x25d3> <1><25d3>: Abbrev Number: 17 (DW_TAG_array_type)    <25d4>   DW_AT_name        : ShortString    <25e0>   DW_AT_data_location: 3 byte block: 97 31 22  (DW_OP_push_object_address; DW_OP_lit1; DW_OP_plus)    <25e4>   DW_AT_type        : <0x25ab> <2><25e8>: Abbrev Number: 18 (DW_TAG_subrange_type)    <25e9>   DW_AT_lower_bound : 1  <25ea>   DW_AT_upper_bound : 3 byte block: 97 94 1  (DW_OP_push_object_address; DW_OP_deref_size: 1) <2><25ee>: Abbrev Number: 0 <1><25ef>: Abbrev Number: 15 (DW_TAG_reference_type)    <25f0>   DW_AT_type        : <0x25c2> <1><25f4>: Abbrev Number: 13 (DW_TAG_typedef)    <25f5>   DW_AT_name        : AnsiString    <2600> DW_AT_type        : <0x2604> <1><2604>: Abbrev Number: 17 (DW_TAG_array_type)    <2605>   DW_AT_name        : AnsiString    <2610>   DW_AT_data_location: 2 byte block: 97 6  (DW_OP_push_object_address; DW_OP_deref)    <2613>   DW_AT_type      : <0x25ab> <2><2617>: Abbrev Number: 18 (DW_TAG_subrange_type)    <2618>   DW_AT_lower_bound : 1    <2619>   DW_AT_upper_bound : 13 byte block: 97 6 12 28 4 0 30 2f 3 0 38 1c 6  (DW_OP_push_object_address; DW_OP_deref; > <2><2627>: Abbrev Number: 22 (DW_TAG_subprogram)    <2629>   DW_AT_name        : ^O�%    <262d>   DW_AT_prototyped  : 0  <262e>   DW_AT_calling_convention: 13 (unknown convention)    <262f> DW_AT_external    : 36    <2630>   DW_AT_type        : <0x65726170> <3><2634>: Abbrev Number: 110      Strange : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i DW_AT_name      : ^O�% The attached file gives all after  $FORMS_$$_finalize$ , which I'm guessing is the end of the LCL variables. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 16:20 You can go back in the output and look for Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  <0>: Abbrev Number: 1 (DW_TAG_compile_unit)      DW_AT_name        : project1.lpr  There will be several. The last one before it fails will give you the unit, in which the error happens. And then maybe a clew what went wrong. Is that one compiled with fpc 3.3.1 (git main branch)? There is maybe something... I need to do some digging. Could be a dead end, but .... ---------------------------------------------------------------------- lazer · 2022-10-19 16:29 There seems to be something wrong with rebuilding LCL.  You told me if you have a system installation it builds locally in $HOME.  That is correct to a point. If I do a " clean up and build " , from IDE it says it cannot write to the lazarus-main tree and  I have to say ignore errors for it build the rest of the project.  But this means that the library stuff does not get built. If I give user write access to those dirs it does not actually alter them and DOES finally create the local builds. It seems there is a bug in the logic which incorrectly asks for write perms to system directories.... which it never actually uses anyway. For last qu: three are three. first my .lpr  ; second interfaces which points to the read-only laz source tree  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i <0><83>: Abbrev Number: 1 (DW_TAG_compile_unit)    <84>   DW_AT_name        : interfaces.pas    <93>   DW_AT_producer    : Free Pascal 3.3.1 2022/10/16  lastly forms, again read only src. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  <0><151>: Abbrev Number: 1 (DW_TAG_compile_unit)    <152>   DW_AT_name        : forms.pp    <15b>   DW_AT_producer    : Free Pascal 3.3.1 2022/10/16 ---------------------------------------------------------------------- lazer · 2022-10-19 16:47 I run laz from command line, I've just noticed that when I do run to cursor it's spamming console with empty stackstrace messages: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Note: (lazarus) [TMainIDE.DoBuildProject] MainBuildBoss.DoCheckIfProjectNeedsCompilation nothing to be done  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace: ---------------------------------------------------------------------- Martin_fr · 2022-10-19 17:41 I'll look at your latest post later. About the missing variables debug info: If you are using FPC 3.3.1, there is some suspicious change in the compiler that may cause this. (Still looking) ---------------------------------------------------------------------- lazer · 2022-10-19 17:51 Thanks. Should I test with 3.2.2  would I need to rebuild laz which was built with 3.1.1 as well ? ---------------------------------------------------------------------- Martin_fr · 2022-10-19 18:09 Quote from: lazer on October 19, 2022, 07:51:43 pmThanks. Should I test with 3.2.2  would I need to rebuild laz which was built with 3.1.1 as well ? You only need to rebuild the project => but that will rebuild the LCL and all too. (which it should do automatically) However the IDE itself (the "lazarus" executable) can be kept as it is. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 18:17 Quote from: lazer on October 19, 2022, 06:29:16 pmThere seems to be something wrong with rebuilding LCL.  You told me if you have a system installation it builds locally in $HOME.  That is correct to a point. If I do a " clean up and build " , from IDE it says it cannot write to the lazarus-main tree and  I have to say ignore errors for it build the rest of the project.  But this means that the library stuff does not get built. You will have to open a new thread on that please. As I said the build system is not exactly in my area of expertise. And since this thread is about debugging, people who might know will not read here. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 18:27 Quote from: lazer on October 19, 2022, 06:47:02 pmI run laz from command line, I've just noticed that when I do run to cursor it's spamming console with empty stackstrace messages: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Note: (lazarus) [TMainIDE.DoBuildProject] MainBuildBoss.DoCheckIfProjectNeedsCompilation nothing to be done  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Stack trace:  Strange, yet another thing I can not reproduce. Maybe this is not just "run to cursor" maybe this is where it fails reading the broken debug info? I'll try later to build a broken exe / With my latest findings I expect to be able to get one => then I can try to harder FpDebug, and report proper errors. (But that it's not urgent right now) Btw, I did check, I can use "run to cursor" (shift F4) to start the debugger. (if the exe is build without the debug info bug) And it also works if, I am on an empty line (so at some time I must have fixed it, and made it look for the next line / probably limited to a certain amount of lines down) ---------------------------------------------------------------------- lazer · 2022-10-19 18:41 Not that was specifically from run to cursor, including the first line. To clarify , run to cursor is working from a cold start with fpDebug, it was gdb where I had to step first.  Now my only gripe with that is , I think it should work once the prog is halted in the debugger, to unconditionally run from where it is ( rather than some step operation). I have just swapped to 3.2.2 , I trashed the laz build tree and did a clean unzip ,  I removed ~/.lazarus , and all the unit stuff in my work directory. I rebuild laz using 3.2.2 and I'm back testing the same code. It ain't right but it's better. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 19:04 Quote from: lazer on October 19, 2022, 08:41:14 pmTo clarify , run to cursor is working from a cold start with fpDebug, it was gdb where I had to step first.  Now my only gripe with that is , I think it should work once the prog is halted in the debugger, to unconditionally run from where it is ( rather than some step operation). And it should: "run to cursor / shift F4"  I did test that earlier today (with FpDebug / have to see, how/if gdb handles it. IIRC gdb should too, but it's a while since I used gdb) Note: it can only stop at blue dots. It will look for the next blue dot, if there is none at the cursor. (which can be in a different procedure). And it may only look a limited amount of lines. If it doesn't you found a bug. --- Just don't accidentality do just F4 as that is "step to cursor" QuoteI have just swapped to 3.2.2 , I trashed the laz build tree and did a clean unzip ,  I removed ~/.lazarus , and all the unit stuff in my work directory. I rebuild laz using 3.2.2 and I'm back testing the same code. It ain't right but it's better. Well let me know what troubles remain. And we will try to hunt them down. ---------------------------------------------------------------------- lazer · 2022-10-19 19:19 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i c/better/different/g Better: I now get a objdump which does not crash.  Now when I run to cursor in a proc owned by my Object I do have content in the "local variables window".  However, this is just the globals.  Actual locals, whether properites of Object or  local vars defined inside the proc are not evaluated. However, a hover says they are not "in current context" ... but it knows where they are ! Quotevar local to proc:  i = var  i: integer = longint bat1.pas(843,5) Quotewordcounter = private var  Tpack.wordcounter: integer = longint bat1.pas(426,5) I do have blue spots but it does not seem to get the context. Inside the Tform code I seem to have normal debuggin. It seems there are issues with anything defined as object and created by clicking in the IDE.  As you say this is "old style" and so I may have not been accounted for.  That seems a more rational situation, even if it does not help debug anything. ---------------------------------------------------------------------- Martin_fr · 2022-10-19 19:40 About objects (old style / not class) / and that applies to all versions of FPC: Quotetype   TFoo = object      MyVal : integer;      procedure bar;   end; procedure TFoo.bar; var   x: integer; begin   X := 1; // If paused here, there will be no "X", nor will there be "self", nor "MyVal" end; var foo: TFoo; begin   Foo.MyVal := 1; // If paused here, you should be able to watch/inspect "Foo" end; If it is a class "TFoo = class ... end;" Then everything should work. Except: Properties that have a Getter. In some case you can actually call the Getter function from the debugger, but often the info about the getter function is incomplete. (This is being worked on in FPC, but no due date yet). I have not yet tested anonymous functions or closures => so no idea what works when they are involved. QuoteCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var Tpack.wordcounter: integer = longintHow exactly is that declared. Quotebut it knows where they are ! Ah but that is 2 different tools. The hint with the location is from the IDE. The same hint will happen if you are not debugging, but just editing. And if you edited the code while you were debugging, then it will show the current location (not the location it had when you compiled). All that is simple parsed from the source code. The debugger does not parse the source code. Because if you edit the source code, the debugger would get things wrong as the source and the exe do no longer match. The debugger solely relies on info the compiler added during compilation. And if it can't get it from this, then it ain't there. ---------------------------------------------------------------------- lazer · 2022-10-19 19:52 OK, I think I have managed to produce a minimal project to display the lack of eval in objects. run to cursor on line 112 . I don't want to rebuild my 3.3.1 setup but if you test that I suspect you will have no locals when in that fn. Neither correct local vars nor the incorrect "locals" which are globals, that I see under 3.2.2 ---------------------------------------------------------------------- Martin_fr · 2022-10-19 20:12 Quote from: lazer on October 19, 2022, 09:52:44 pmrun to cursor on line 112 . Yes (as in my post above), there are no locals. You can also see in the stack window that the function is show using a mangled name    DEBUGGER_TEST1$_$TPACK_$__$$_OBJFN$$LONGINT The problem is that all versions of FPC have a bug: They don't write debug info for those methods. FPC actually writes info about the lines. But FPC does not include info that there is a function (the mangled name is actually from the info for the linker, which the debugger also reads). Without knowing of the function, the debugger can't know about local vars. (And "self" is a local var too, so no self either / and no fields that require self to reach them) In a simple case like this, and if you can find out the register in which the pointer to the the "object" is held (if there is such a register), then you can do    ^Tpack(%rcx) But that is only valid on certain lines, since register usage changes. There is a bug report for that https://gitlab.com/freepascal.org/fpc/source/-/issues/37661 ---------------------------------------------------------------------- lazer · 2022-10-19 20:20 QuoteBut FPC does not include info that there is a function So it's known bug which should have been fixed long ago.  It does not sound that hard to add info that there is  a function.  Is this, like I suspected, that this has only been written to classes and not objects ? How does this test project work under 3.3. 1 ?   does it produce broken objects and empty local vars ? ---------------------------------------------------------------------- Martin_fr · 2022-10-19 20:53 Quote from: lazer on October 19, 2022, 10:20:56 pmQuoteBut FPC does not include info that there is a function So it's known bug which should have been fixed long ago.  It does not sound that hard to add info that there is  a function.  I'm not actually one of the FPC developers. So I don't know the details. QuoteHow does this test project work under 3.3. 1 ?   does it produce broken objects and empty local vars ? Actually I just tested it, and it seems to work. The broken dwarf is not triggered because the project has no "ansistring" (and there is a 2nd type that triggers it, but not sure which / some string or array probably) --- I don't know how long the issue has been fixed (and if it is completely fixed). But if you can build an fpc 3.3.1 from before 10th OCT => it might work. EDIT: or wait a day or two. A fix for the other fpc issue is likely on the way https://gitlab.com/freepascal.org/fpc/source/-/issues/39928 ---------------------------------------------------------------------- lazer · 2022-10-19 21:07 I try to stick with pascal strings and %H- but since many library calls require ansistring that means a fair bit of flitting. I'm not surprised this causes issues. With pascal strings, Pchar ( C style ) stings  and then the ugly ref counted ansistrings with fake Pchar typecast syntax , it's a nightmare to keep track of.  I'm not at all surprised those trying to make all this hand together have trouble. I've spend more time this week debugging the IDE than working on my project. This is clearly not usable as it is in any version .  I need to get away from this object definition. Were you suggesting it would work better as a Tclass ? ---------------------------------------------------------------------- Martin_fr · 2022-10-19 21:58 Quote from: lazer on October 19, 2022, 11:07:22 pmI try to stick with pascal strings and %H- but since many library calls require ansistring that means a fair bit of flitting. I'm not surprised this causes issues. With pascal strings, Pchar ( C style ) stings  and then the ugly ref counted ansistrings with fake Pchar typecast syntax , it's a nightmare to keep track of.  I'm not at all surprised those trying to make all this hand together have trouble. Actually the bug (that is seen by objdump) is quite simple. The fact that it is caused be ansistring and dynarray is kinda coincidence. Someone added more info to the dwarf description, and the forgot to increase the size of the data-container. (which is simply a list of bytes, but that can overflow) Those things happen. Actually it had happened before, a few years back. Hence I recognized it that fast, when I saw the objdump. QuoteI've spend more time this week debugging the IDE than working on my project. This is clearly not usable as it is in any version .  I know the feeling. QuoteI need to get away from this object definition. Were you suggesting it would work better as a Tclass ? Well it seems it might be fixed in 3.3.1 / as soon as the other thing is fixed, and hoping there is no other 3.3.1 issue.... 3.3.1 is always living on the edge. You need to find a revision that is good for you. Once you have that => fine. A very quick replacement is advanced records. https://wiki.freepascal.org/Record#Advanced_record Same layout in memory. But you loose private/public/constructor... Also, if you use "object" without new()/pointer => then the memory is on the stack, and you do never need to free it, because it just goes out of scope. The same holds for records and advanced records. Since you use pointers to your object, and create them with "new()", you might consider "class". Because they already have the pointer build in. However, they don't get freed when going out of scope. ---------------------------------------------------------------------- lazer · 2022-10-19 22:22 QuoteSomeone added more info to the dwarf description, and the forgot to increase the size of the data-container. (which is simply a list of bytes, but that can overflow) So it's just a simple change to a declaration ?  Since I'm building from source, can you tell me what I need to change ? ---------------------------------------------------------------------- Martin_fr · 2022-10-19 22:34 Quote from: lazer on October 20, 2022, 12:22:09 amQuoteSomeone added more info to the dwarf description, and the forgot to increase the size of the data-container. (which is simply a list of bytes, but that can overflow) So it's just a simple change to a declaration ?  Since I'm building from source, can you tell me what I need to change ? https://gitlab.com/martin_frb/fpc- src/-/commit/818a7ceb64e9d52a2850c8b336a9d47d5a617df4 This is the commit that fixes it. You can view it as diff or pull it. IIRC (within your fpc git dir) git pull https://gitlab.com/martin_frb/fpc-src.git  818a7ceb64e9d52a2850c8b336a9d47d5a617df4 git switch -c  fpc331-fixed  818a7ceb64e9d52a2850c8b336a9d47d5a617df4 ---------------------------------------------------------------------- PascalDragon · 2022-10-20 05:25 Quote from: Martin_fr on October 19, 2022, 11:58:43 pmA very quick replacement is advanced records. https://wiki.freepascal.org/Record#Advanced_record Same layout in memory. But you loose private/public/constructor... But these do work with records? Only real important features you'll miss out on with Advanced Records are inheritance and thus virtual methods. ---------------------------------------------------------------------- lazer · 2022-10-20 05:47 Thanks, I will build your tree and give that a try. Could I suggest that 17 becomes a named constant to make this more robust: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i       DW_LNE_set_segment  = $04;      DW_LNE_lo_user      = $80;      DW_LNE_hi_user      = $ff;       {  keep this upto date with above const defintions !! }      DWEEB_COUNT = DW_LNS_set_isa +1 + DW_LNE_set_segment;  // currently  17;  14 similarly , could be either DWEEB_COUNT-3 or better DWEEB_COUNT +sizeOf(4byteType)-sizeOf(onebytType) , which I'm guessing is the origin of the size difference. Using hardcoded numeric constants for this kind of thing is risky and harder to maintain. Having been caught out twice by this , it would be good to code it in a more robust way. I'm confused. :? I only had a src tarball, not a git repository, so I edited by hand. First I did make all on the virgin code.  Then I add DWEEB_COUNT , saved it and did make all again. It tells me "nothing to do".  Isn't the whole point of make that it checks for any timestamps newer than the related object code and rebuilds any deps? ---------------------------------------------------------------------- Martin_fr · 2022-10-20 07:56 Quote from: lazer on October 20, 2022, 07:47:01 amThanks, I will build your tree and give that a try. Could I suggest that 17 becomes a named constant to make this more robust: I am not sure where your code quote comes from. The 17 is not related to the count of constant or such, but how many are added to current_asmdata.asmlists[al_dwarf_info] at that point. https://lists.freepascal.org/pipermail/fpc- devel/2022-October/044819.html QuoteI'm confused. :? I only had a src tarball, not a git repository, so I edited by hand. ok. QuoteFirst I did make all on the virgin code.  Then I add DWEEB_COUNT , saved it and did make all again. It tells me "nothing to do".  Isn't the whole point of make that it checks for any timestamps newer than the related object code and rebuilds any deps? Sorry, but I am not too much acquainted with Makefiles... ---------------------------------------------------------------------- Martin_fr · 2022-10-20 07:58 Quote from: PascalDragon on October 20, 2022, 07:25:06 amQuote from: Martin_fr on October 19, 2022, 11:58:43 pmA very quick replacement is advanced records. https://wiki.freepascal.org/Record#Advanced_record Same layout in memory. But you loose private/public/constructor... But these do work with records? Only real important features you'll miss out on with Advanced Records are inheritance and thus virtual methods. In that case, I must have done something wrong when I tested. Sorry. ---------------------------------------------------------------------- ccrause · 2022-10-20 08:19 Quote from: lazer on October 20, 2022, 07:47:01 amFirst I did make all on the virgin code.  Then I add DWEEB_COUNT , saved it and did make all again. It tells me "nothing to do".  Isn't the whole point of make that it checks for any timestamps newer than the related object code and rebuilds any deps? Try make clean all. The make file is full of conditional checks to cater for different (cross) targets.  When a specific target was built successfully the make file creates a file stamp (depending on the make options either build-stamp.${FULL_TARGET} or base.build-stamp.${FULL_TARGET}) to indicate the particular target was built successful and should not be repeated (or something to this effect using make logic). ---------------------------------------------------------------------- lazer · 2022-10-20 08:32 Quote to indicate the particular target was built successful and should not be repeated (or something to this effect using make logic). Thanks for the explanation. Well I suppose you can program any kind of crazy stuff you want but that pretty much  disables entire working of Makefiles. You can write whatever dependency rules you want but usually you make the executable depend on all the unit object files it needs and all the object file depend on the source files. That way if you "touch"  a source file anything which refers to it get rebuilt. It sounds like someone who did not understand Makefiles did this. That kind of silliness is I why I don't trust make clean all either in laz/FPC.  I just delete the tree and do a fresh extraction. ---------------------------------------------------------------------- lazer · 2022-10-20 08:33 QuoteI am not sure where your code quote comes from. The 17 is not related to the count of constant or such, but how many are added to current_asmdata.asmlists[al_dwarf_info] at that point. That code snip was my suggestion of a line to add.  I was just guessing what the 17 was from. Since you say it's from that array, set a variable to the length of that array at the top of procedure addstringdef() .   (I suspect it may be the same thing at the end of the day but using the array dimension is the definitive thing you need to match). How about: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i DWEEB_COUNT := high(current_asmdata.asmlists);  Hardcoding numeric  constants is just asking for trouble. Expecting someone adding a new data type to know that there is some hardcoded gotcha hidden in the source is crazy.  You may get away with it if it's just one guy, with a good memory, maintaining the whole thing but it's very poor software design. ---------------------------------------------------------------------- lazer · 2022-10-20 14:22 OK . I've done yet another complete rebuild. Removed fpc and laz source, all configs and local builds of lib files. Rebuilt and installed fpc using distro 3.2.2 ; removed distro fpc hand patched dbdwarf.pas  ##  git said it needed to rebase ! Rebuilt lazarus Ran laz, set up compile src in start up IDE. Set project debug to dwarf3 Build Set into : great. Stops on first line of lpr file with blue dots Bad news no blue dots in my main pas file . No debuggering at all. I'm done with this crap. I've spent an entire week battling the IDE and debuggerer and sod all work done. Lazaraus will go back of the shelf for another 5 years.  Still not usable. Sadly.  Will it ever be ? ---------------------------------------------------------------------- Чебурашка · 2022-10-20 14:53 Quote from: lazer on October 20, 2022, 04:22:14 pmcrap. Not good. ---------------------------------------------------------------------- lazer · 2022-10-21 02:45 https://gitlab.com/freepascal.org/fpc/source/- /commit/dd0711a27e85d15d45dc47e7b014c6bcc3fbf230 So this has been "fixed" by bumping the hardcoded integers instead of fixing the real problem that of using hand coded constants instead of a value derived from the structure. The issue has been closed and will be forgotten about until next time, in a year or two, when someone needs to add another DW entry and it will start breaking again. That is why fpc is unstable and unreliable. ---------------------------------------------------------------------- Чебурашка · 2022-10-21 06:32 Quote from: lazer on October 21, 2022, 04:45:18 amhttps://gitlab.com/f reepascal.org/fpc/source/- /commit/dd0711a27e85d15d45dc47e7b014c6bcc3fbf230 So this has been "fixed" by bumping the hardcoded integers instead of fixing the real problem that of using hand coded constants instead of a value derived from the structure. The issue has been closed and will be forgotten about until next time, in a year or two, when someone needs to add another DW entry and it will start breaking again. That is why fpc is unstable and unreliable. You could propose a patch to implement your idea. If it results in a more effective/efficient code, it would be helpful to everyone. ---------------------------------------------------------------------- lazer · 2022-10-21 06:41 QuoteYou could propose a patch to implement your idea. If it results in a more effective/efficient code, it would be helpful to everyone. I have pointed out exactly what needs to be done. It's probably one line of code. Someone familiar with code base needs to work out exactly what variable is concerned. ---------------------------------------------------------------------- Martin_fr · 2022-10-21 09:12 Quote from: lazer on October 21, 2022, 08:41:46 amQuoteYou could propose a patch to implement your idea. If it results in a more effective/efficient code, it would be helpful to everyone. I have pointed out exactly what needs to be done. It's probably one line of code. Someone familiar with code base needs to work out exactly what variable is concerned. Before I add my opinion: I am not the maintainer of that code. Nor part of the FPC team (of course I do have contact with that team, due to my work on Lazarus). Hence, the below is an "outsiders view". I do however have enough code under my own maintenance for which I continually face the need for decisions on what to fix/improve/add in which order. I.e., there is code of mine that has seen some heavy shortcut taking. But without this, today we would still use gdb (and believe me in 99% of all cases, this is way worse than FpDebug is today). I am not saying that it is a good thing to take those shortcuts. But in the real world, with the resources (e.g. man hours) that are available (or rather those that are not), this is what happens. From what I saw of that code, it's more than a line. It would likely require an additional sub-stream of bytes, so a count can be established for that. That would at the very least mean: - everywhere were it is used, there must be a new statement added to tell the sub-stream it is complete. - depending on implementation create/free memory for this may be needed (that can be worked around, but that may introduce other limitations/trickery) Besides there are "sub-sections" with their own counts within those sub-streams. So they would require further nested/recursive sub-sub- streams.... It quickly adds up to a medium large amount of new code needed. And that then means, it's enough work to trigger the choice: - improve this code - fix some/several other bugs instead Since the total amount of available man hours is fixed, it is either or. And yes of course, if we assume, that every 2 or 3 years this gets broken, and it will take (worst case) an hour to fix (reality is more like 10 minutes), then in a some decades the time spent on improving that code will be recovered. The "time to fix" does not include end-user time/experience. Because if this does get fixed, something else remains broken (or missing / not-implemented). And then that something else will cause the same dent to the user experience. On top of that, due to the nature of those bugs, they will always (as in 99.99%) be noted "within days". So releases wont be affected. IMHO, for one of the 2 broken bits, there is still a case to be made for a constant, because of the repetition of the integer in the code. That would however not change the likelihood of this kind of bug. At this point, that would be merely cosmetic. Of course, in your case the last released FPC is missing debug info for "object", so you are forced to use 3.3.1 => and that comes with the label "occasionally broken". Btw, in my experience the above can be applied to any other software (from a certain code size/complexity upwards) ---------------------------------------------------------------------- lazer · 2022-10-21 09:39 QuoteFrom what I saw of that code, it's more than a line. It could be made more complicated. However,  the fact that it currently runs with a numerical constant proved this does not have to be a dynamic runtime calculation. Rather that constant needs to be related to the definition of the variable which causes the overflow. If a new DW data type is added it breaks the output and that can be fixed by adding 1 to the  magic numbers, means that someone just needs to identify  what data type change caused the breakage and use something like sizeOf() or length() on that. Someone has calculated that 17, it's not pulled from the air as a  "probably big enough " value. You seem familiar with the change that caused the last two breakages, What was changed? Was it anything to do with Tdwarf_type , which happens to be 17 bytes long ? The repetitions of the test could easily be removed by use of a binary and that would be cleaner, though that would not affect issue of the magic numbers. ---------------------------------------------------------------------- Martin_fr · 2022-10-21 10:34 The repetition of the "17" and the bug are not related. See the other code block, where a constant was fixed, and that constant was not repeated (14 replaced by 15). If that number had just been a constant "const FOO_LEN = 14" => it would still have had to be changed by hand => and still have the same potential to be overlooked. The 17  is the byte length of all the "operations" (statements/commands) and their argument in that binary stream. Sure that len can be calculated. But that means to change how the "operations" are added, so they can be determined as such, and can be counted. Yet that only scratches the surface of the problem. There are "operations" that contain the length of a set of other "operations" => so they also need to be added, in such a way that they can be detected. Those can be nested and/or overlapping.... A lot of data to keep track of... Basically the code in questions writes a small "program" in "dwarf" => the alternative to hardcoding stuff would be a small "dwarf" compiler. Which would end up to be a ton of extra code (and within that, most likely some extra bugs). From a theoretical point of design: great. From a cost benefit point of view: not so much. Yes, of course there are less expensive ways. But they still be significant work. And the real live benefit is very small. And the loss is that other bugs will have to be deferred. IMHO, this is code that can be improved, when all other bugs are fixed, and no important features are missing any more. In other words: If someone has the time to do as much work as that would require => there is a huge list of things that are way more urgent to be done. But as I said, I am not in charge of that code (nor to I aim for being in charge of it) ---------------------------------------------------------------------- lazer · 2022-10-21 10:50 QuoteThe repetition of the "17" and the bug are not related.Exactly what I've said on more than one occasion.  Quote"const FOO_LEN = 14" => it would still have had to be changed by hand => and still have the same potential to be overlooked.That is why I have been saying all along it needs to be calculated programatically , I never suggested just naming it would change anything. QuoteThe 17  is the byte length of all the "operations" (statements/commands) and their argument in that binary stream. Sure that len can be calculated. But that means to change how the "operations" are added, so they can be determined as such, and can be counted. You keep insisting on that but it is not consistent the existing code which uses a hard coded numerical constant. How is the is fixed value of 17 calculated and what was the variable/record change which caused the problem?  You seem to have indicated that it was an extra DW tag value which was added. Where can I find that ? Can you link to something concrete? Either a variable name or a commit which caused the breakage? ---------------------------------------------------------------------- Martin_fr · 2022-10-21 11:14 Quote from: lazer on October 21, 2022, 12:50:01 pmQuoteThe repetition of the "17" and the bug are not related.Exactly what I've said on more than one occasion. Ok, so we misunderstood each other on this... To be clear: replacing the 17 by a constant (or even using a boolean) => great => yet, not my call to make QuoteQuote"const FOO_LEN = 14" => it would still have had to be changed by hand => and still have the same potential to be overlooked.That is why I have been saying all along it needs to be calculated programatically , To which I said: 1) I anticipate the amount of work to be greater than the time it will save in several decades. 2) "   If someone has the time to do as much work as that would require => there is a huge list of things that are way more urgent to be done.  " QuoteHow is the is fixed value of 17 calculated and what was the variable/record change which caused the problem?  You seem to have indicated that it was an extra DW tag value which was added. Where can I find that ? Can you link to something concrete? Either a variable name or a commit which caused the breakage? The breaking commit is mentioned in the fixing commit Fix: https://gitlab.com/freepascal.org/fpc/source/- /commit/dd0711a27e85d15d45dc47e7b014c6bcc3fbf230 Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Issue #39928 introduced in 1b698210Broken: https://gitlab.com/martin_frb/fpc- src/-/commit/1b6982107f1ac4b4111e37be0a3649d155a2bc1e Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i    current_ asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP _nop)));Adds one more byte into the list. (there are also ops that add several bytes in one "tai_const") That most outer count can be tracked with moderate effort. Though it depends if you want to add new local variables in lots of places, or have a more "re-usable" solution. But for example Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i         cur rent_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord( DW_OP_bra)));        current_asmdata.asmlists[al_dwarf_info].concat(ta i_const.create_16bit_unaligned(5)); The "5" is a nested sub list of 5 bytes. And of those there can be any amount of nesting and/or overlap. And they can cause the same issue. Check in how many places lists like this are build.  (If the idea is to add (several) local vars as counters in each of those places => I have an inkling it will not be liked. (But I don't know)) Just a reminder, any discussion with me about this, is mainly for entertaining the point. - I am not in charge of this code. I can not decide or affect what will happen there. - I merely give my personal judgment on the cost/benefit (and an implied second-guessing that those in charge may have a similar conclusion) ---------------------------------------------------------------------- lazer · 2022-10-21 12:48 Thanks for the info. So it seems that the hard coded 17 is purely an empirical hack established by trial and error !  It is none the less constant. If it is that clunky, it could at least be trapped by an assert() so that it gets trapped if it ever changes.  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   type    TAsmList = class(tlinkedlist)         section_count : longint;         constructor create;         function  getlasttaifilepos : pfileposinfo;         { inserts another List at the begin and make this List empty }         procedure insertList(p : TLinkedList); override;         { inserts another List before the provided item and make this List empty }         procedure insertListBefore(Item:TLinkedListItem;p : TLinkedList); override;       { inserts another List after the provided item and make this List empty }         procedure insertListAfter(Item:TLinkedListItem;p : TLinkedList); override;         { concats another List at the end and make this List empty }         procedure concatList(p : TLinkedList); override;         { concats another List at the start and makes a copy           the list is ordered in reverse.         }         procedure insertListcopy(p : TLinkedList); override;         { concats another List at the end and makes a copy }         procedure concatListcopy(p : TLinkedList); override;         { removes all items from the list, the items are not freed }         procedure RemoveAll; override;         procedure concat (Item:TLinkedListItem); override;    end;       procedure TAsmList.Concat(Item:TLinkedListItem);      begin         assert(Item.section_count>16,'magic number needs adjusting');         inherited Concat(Item)      end; ---------------------------------------------------------------------- Martin_fr · 2022-10-21 13:04 Quote from: lazer on October 21, 2022, 02:48:58 pmSo it seems that the hard coded 17 is purely an empirical hack established by trial and error !  It is none the less constant. It is the amount of bytes in the list/stream. And it must be exact. Not 1 more, not 1 less. Quote from: Martin_fr on October 21, 2022, 12:34:06 pmThe 17  is the byte length of all the "operations" (statements/commands) and their argument in that binary stream. It's defined by the DWARF specification. If it's wrong the next block can not be found. And the current block is either truncated, or data from the next block will be included (and likely not be process-able in the context). And hence the debugger did not find any data... ---------------------------------------------------------------------- lazer · 2022-10-21 13:14 QuoteIt is the amount of bytes in the list/stream. And it must be exact. Not 1 more, not 1 less. Quote from: Martin_fr on Today at 12:34:06 pm     The 17  is the byte length of all the "operations" (statements/commands) and their argument in that binary stream. It's defined by the DWARF specification. So if I follow you , it is not the value 17 which is defined ( since we just changed that and added the nop ) but the fact that it must beconsistent across the stream and exactly matched in each record. Is that correct ? Or maybe it is fixed at 17 and was not respected before and that is they nops were added ? ---------------------------------------------------------------------- Martin_fr · 2022-10-21 13:40 Quote from: lazer on October 21, 2022, 03:14:17 pmQuoteIt is the amount of bytes in the list/stream. And it must be exact. Not 1 more, not 1 less. Quote from: Martin_fr on Today at 12:34:06 pm     The 17  is the byte length of all the "operations" (statements/commands) and their argument in that binary stream. It's defined by the DWARF specification. So if I follow you , it is not the value 17 which is defined ( since we just changed that and added the nop ) but the fact that it must beconsistent across the stream and exactly matched in each record. Is that correct ? Yes, its part of a header, followed by data. (if the data is nop or other does not matter / just the size of the data). The size is variable, and the header has the size for each record. And there are many different records following each other. But also, inside the record, there are groups. And the size of those is encoded within the record, before each group. Those groups can be nested and/or overlap. (like (conditional-)branch statements in asm). So it's not just tracking the main record. It's tracking each group within too. Just to say, if you want to propose a patch => check with the fpc team what they will accept. (As I said, I have no say on that code). ---------------------------------------------------------------------- lazer · 2022-10-21 13:58 QuoteSo it's not just tracking the main record. It's tracking each group within too.This is what you've been saying all along but how is that consistent with it currently being programmed with a constant ? ---------------------------------------------------------------------- Martin_fr · 2022-10-21 14:52 Quote from: lazer on October 21, 2022, 03:58:43 pmQuoteSo it's not just tracking the main record. It's tracking each group within too.This is what you've been saying all along but how is that consistent with it currently being programmed with a constant ? It's manually tracking each group within too. The value is adjusted by the programmer, to (keep) track (of) the amount of bytes added by the various "operations" that are added to the stream. I though that was self-evident, since you lobbied for that to be changed so the code would to the counting. ---------------------------------------------------------------------- lazer · 2022-10-21 15:25 Thanks.  IMO none of this right, which may explain a few things. The hard coded values should now be 14 and 16, so 17 is still buggy. There is another hard coded const  14 which needs to be 15 now there's a new op ! It seems that the progammer counts up in the source code how many bytes each line is adding then pre-empts the assignments in setting the record length.  The manual counting does not seem very reliable Here is a slight rearrangement where the length of list is monitored and the records set based on the ACTUAL DATA written . It does compile but I can't test it because my debugger is buggered, so I can't know whether I've made it worse, or better.  There's about three places this simple rearrangement needs to be done, so it's not a major rewrite. This will fix the "14" , just before  "17" bugginess.  There's some 2 byte blocks which can probably be trusted to take care of themselves but to be rigorous maybe should get the same treatment. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i    procedure tdebuginfodwarf3.appenddef_array(list: tasmlist; def: tarraydef);    var tmpcount:integer;      begin        if not is_dynamic_array(def) then          begin            inherited appenddef_array(list,def);            exit;          end;         if assigned(def.typesym) then          append_entry(DW_TAG_array_type,true,[            DW_AT_name,DW_FORM_string,symname(def.typesym, false)+#0,            DW_AT_byte_stride,DW_FORM_udata,def.elesize,            DW_AT_data_location,DW_FORM_block1,2            ])        else        append_entry(DW_TAG_array_type,true,[            DW_AT_byte_stride,DW_FORM_udata,def.elesize,            DW_AT_data_location,DW_FORM_block1,2            ]);        current_asm data.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_pu sh_object_address)));        current_asmdata.asmlists[al_dwarf_info].c oncat(tai_const.create_8bit(ord(DW_OP_deref)));         append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));      finish_entry;          tmpcount:=current_asmdata.asmlists[al_dwarf_info].section_count;      { to simplify things, we don't write a multidimensional array here }        current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_ 8bit(ord(DW_OP_push_object_address)));        current_asmdata.asmlists [al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_deref)));      current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit( ord(DW_OP_dup)));        { pointer = nil? }        current_asmdata.asm lists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_bra)));      current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_16 bit_unaligned(5));        { yes -> length = 0 }        current_asmdata .asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_const1 s)));        current_asmdata.asmlists[al_dwarf_info].concat(tai_const. create_8bit(byte(-1)));        current_asmdata.asmlists[al_dwarf_info] .concat(tai_const.create_8bit(ord(DW_OP_skip)));        current_asmdat a.asmlists[al_dwarf_info].concat(tai_const.create_16bit_unaligned(3));       { no -> load length }        current_asmdata.asmlists[al_dwarf_ info].concat(tai_const.create_8bit(ord(DW_OP_lit0)+sizesinttype.size)) ;        current_asmdata.asmlists[al_dwarf_info].concat(tai_const.crea te_8bit(ord(DW_OP_minus)));        current_asmdata.asmlists[al_dwarf_i nfo].concat(tai_const.create_8bit(ord(DW_OP_deref)));        { skip to past end is not allowed, thus use a nop here }        current_asmdata. asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_nop)));       append_entry(DW_TAG_subrange_type,false,[          DW_AT_lower_bound,DW_FORM_udata,0,          DW_AT_upper_bound,DW_FORM_block1, current_asmdata.asmlists[al_dwarf_info].section_count-tmpcount  // was hardcoded 14          ]);        append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.rangedef));       finish_entry;         finish_children;      end;  Tell me if that makes sense to you. ---------------------------------------------------------------------- Martin_fr · 2022-10-21 15:45 Changing the order of the code, will break it. Also: having to add local vars to every method that deals with this => in my opinion (but others may think different) that makes it worse. IMHO The house keeping should be entirely hidden in the object that stores the data. But yes in theory that is how to calc the length. But again, all up to the FPC team. ---------------------------------------------------------------------- lazer · 2022-10-21 16:12 Thanks for taking a look. QuoteChanging the order of the code, will break it. Ah indeed, append_attribute adds the headers to the same list. So the best thing is just to use and assert to make sure the data added matches what the author guessed the byte count to be . Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i            assert(current_asmdata.asmlists[al_dwarf_info].section_count-tmpcount = upperopcodes, ' data written does not match upperopcodes');  Quote in my opinion (but others may think different) that makes it worse.the of cost one integer variable on the stack ?!  That is not worse than people breaking up the code because they can't count . ---------------------------------------------------------------------- Martin_fr · 2022-10-21 16:18 Quote from: Martin_fr on October 21, 2022, 05:45:51 pmChanging the order of the code, will break it.. Actually, come to think of it => That needs to be checked with the dwarf spec. Might be possible. There are 2 lists. But I have to check what goes into which. ---------------------------------------------------------------------- Martin_fr · 2022-10-21 16:27 Quote from: lazer on October 21, 2022, 06:12:00 pmthe cost one integer variable on the stack ?!  There are over 20 DW_FORM_block*. (not sure what else) Afaik each of them has a len. All that code needs to be refactored. The cost of a variable is not the issue. But for me personally, if the object is to make it do the job on its own, I would expect the list object to handle this. Just tell it, here is the start, and here is the end, and it will do the job. Of course you have DW_OP_bra, DW_OP_skip (not sure if others). Currently not much used, but that could change. And they also need that functionality. Again, the fpc team may consider this different. I don't know. And in the end, it is whatever they say. ---------------------------------------------------------------------- lazer · 2022-10-21 17:02 I don't think they all need doing. Most are 1,2,or 3 byte writes, which I hope people can program reliably. The two I've highlit are the only two were problems are likely.  With the integer and an assert(), I think that would be sufficient to ensure this is more robust and does not reoccur. ---------------------------------------------------------------------- Martin_fr · 2022-10-21 17:51 What might be better in that case, is a test case. Thanks to gitlab CI they are run regularly. Anyway, needs to be discussed with the fpc team. ---------------------------------------------------------------------- Martin_fr · 2022-10-21 17:52 Different topic: You said you still had trouble with the debugger, after that fix (the fix as it currently exists). ---------------------------------------------------------------------- lazer · 2022-10-21 19:13 I'm just testing my assert() mod on the two procs affected by the patch, without the reordering. It's fairly same on a simple project but still no blue dots on the real project, apart from in the lpr file. ---------------------------------------------------------------------- Martin_fr · 2022-10-21 19:16 see what   objdump --dwarf=decodedline project shows? You can also check if   objdump --dwarf=info project shows anything for that unit (searching for a compilation unit with that name) ---------------------------------------------------------------------- lazer · 2022-10-21 19:26 while redirecting output to a file, I'm still getting this directly to console. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i objdump: Warning: Bogus end-of-siblings marker detected at offset 39aa7 in .debug_info sectionobjdump: Warning: Bogus end-of-siblings marker detected at offset 39c1b in .debug_info sectionobjdump: Warning: Bogus end-of-siblings marker detected at offset 39c84 in .debug_info section objdump: Warning: Further warnings about bogus end-of-sibling markers suppressed  Also in the obj file a few cases like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  <1><89377d>: Abbrev Number: 43 (DW_TAG_array_type)    <89377e>   DW_AT_byte_size   : 40    <89377f>   DW_AT_byte_stride : 40    <893780>   DW_AT_type        : <0x89320d> <2><893784>: Abbrev Number: 44 (DW_TAG_subrange_type)    <893785>   DW_AT_lower_bound : 0    <893786>   DW_AT_upper_bound : 0  Is that legit ? o/w I see my varaibles with appropriate initial values. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  CU: bat1.pas:File name                            Line number    Starting address    View    Stmtbat1.pas                                     629            0x466520               xbat1.pas                                   629            0x46655c               xbat1.pas                                   630            0x466583               xbat1.pas                                     631            0x466598             xbat1.pas                                       0          0x4665a3bat1.pas                                     632            0x4665a8               xbat1.pas                                     0            0x4665b1bat1.pas                                     632            0x4665c5               xbat1.pas                                     -            0x4665ce  I guess the x column corresponds to blue dots but I don't get them in IDE. ---------------------------------------------------------------------- Martin_fr · 2022-10-21 21:22 I have to see if I can find something about those "bogus" markers. If you search for the offset in the output (I think in the <>)  then what data is at those locations. The array looks like    type TFoo = array [0..0] of TData where sizeOf(TData) = 40 Yes the "x" (or any line number >= 1) should be the blue dots. The 0 lines are known. I don't recall the exact background. So "bat1.pas" should have blue dots. But what about the unit where you did not see blue dots? - Is it in the decodedlines? - Does the unit name appear in the "info" section (i.e. are variables for those units described)? - Are you sure the code is in the exe?   This may sound strange, but if you have a procedure that  is never called (nor otherwise referenced), then it may be left out. ---------------------------------------------------------------------- lazer · 2022-10-22 05:00 OK. Yes, the program runs , I get the main window and it closes without error. QuoteSo "bat1.pas" should have blue dots. But what about the unit where you did not see blue dots? That file included the main window and the previously meantioned Object which I now declare as a class  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type   Ppack=^Tpack;  Tpack= class    private  This project only has one form in one pas file. ( I removed the about dlg to simplify). Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   function fileexpand(fn:string; s:AnsiString):Pchar;  begin  // line 629 of bat1.pas    fn:=s;    result:= @fn;  end;  That code is not called and is a global function outside the Form class, so not much optimisation cutting out code. QuoteI have to see if I can find something about those "bogus" markers. If you search for the offset in the output (I think in the <>)  then what data is at those locations. The array looks like    type TFoo = array [0..0] of TData where sizeOf(TData) = 40 the first bogus end-of-siblings marker, the last looks similar: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  <1><39a91>: Abbrev Number: 68 (DW_TAG_subrange_type)    <39a92>   DW_AT_lower_bound : 0    <39a93>   DW_AT_upper_bound : 14 byte block: 97 6 12 28 5 0 9 ff 2f 3 0 38 1c 6   (DW_OP_push_object_address; DW_OP_deref; DW_OP_dup; DW_OP_bra: 5;>    <39aa2>   DW_AT_type        : <0x252196> <1><39aa6>: Abbrev Number: 0 <0><39aa7>: Abbrev Number: 0 <-1><39aa8>: Abbrev Number: 15 (DW_TAG_reference_type)    <39aa9>   DW_AT_type        : <0x39a63> <-1><39aad>: Abbrev Number: 13 (DW_TAG_typedef)    <39aae>   DW_AT_name        : TVarRec    <39ab6> DW_AT_type        : <0x39aba>  the second one:  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i <0><39c0c>: Abbrev Number: 30 (DW_TAG_member)    <39c0d>   DW_AT_name        : VQWord    <39c14>   DW_AT_data_member_location: 2 byte block: 23 8  (DW_OP_plus_uconst: 8)    <39c17>   DW_AT_type        : <0x3ccf6> <0><39c1b>: Abbrev Number: 0 <-1><39c1c>: Abbrev Number: 15 (DW_TAG_reference_type)    <39c1d>   DW_AT_type        : <0x39aad> <-1><39c21>: Abbrev Number: 13 (DW_TAG_typedef)    <39c22> DW_AT_name        : PChar    <39c28>   DW_AT_type        : <0x39c2c> <-1><39c2c>: Abbrev Number: 19 (DW_TAG_pointer_type) ---------------------------------------------------------------------- Martin_fr · 2022-10-22 11:36 With all the testing that you have done, are you sure your compiler has the full fix? Especially line 3964 changed from "14" to "15" ? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i           DW_AT_upper_bound,DW_FORM_block1,15 Because your objdump looks like it still puts a 14 in there. You may want to consider using git. That will make updating easier for you. Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i # clone into directory fpc_gitgit clone https://gitlab.com/freepascal.org/fpc/source.git ./fpc_git # update (if you have no modificationsgit pull # export the source to the build directory# fpc_source_for_build is where you will run make / and what you will give the IDE as fpc source dir# this may not copy local modifications / you can modify the export # if needed, eitherrm -rf /path/to/fpc_source_for_build/*mkdir /path/to/fpc_source_for_build git  --git-dir=/path/to/fpc_git/.git  --work- tree=/path/to/fpc_source_for_build  restore  . # see modifications you made in your fpc_source_for_build git  --git-dir=/path/to/fpc_git/.git  --work-tree=/path/to/fpc_source_for_build  diff # temporary save your changes from fpc_source_for_build  git  --git- dir=/path/to/fpc_git/.git  --work-tree=/path/to/fpc_source_for_build  stash push# then overwrite fpc_source_for_build  with an update# and restore the changes to fpc_source_for_build git  --git- dir=/path/to/fpc_git/.git  --work-tree=/path/to/fpc_source_for_build  stash pop   Or make a local branch for your changes, if you go into playing a lot with the fpc sources Mind you, the above git syntax is way more complex that any git you normally ever find. This is because a 2nd directory is created for the fpc build process. And we use (abuse) git to copy the files. You can just copy your entire git dir, and then delete the .git Then changed files in your git dir will be copied with the changes (in the above you would need to commit them to copy the changes / or add them to the index and use a diff syntax) So are the blue dots solved then? ---------------------------------------------------------------------- lazer · 2022-10-22 15:54 Sorry I should have rerun objdump again, it may have been old. I already moved to using git.  To be sure, I removed everything in sight. fpc libs configs, source trees, the lot. I pulled a clean tree for fpc and laz. Built fpc with distro 3.2.2 This time I installed to /usr/local/lib which is probably where this should have gone to start with. I reset symlink to 3.1.1 and build lazarus. Now it looks a bit cleaner: no sibling probs and I have blue dots everywhere I'd expect them. ( debugging set to dwarf3 ) However, the good news stops there. I can step into lpr file but breakpoints and run to cursor inside the pas file have no effect , it's just like a normal Run. At least it looks a bit more sane. The trivial test prog steps and debugs as expected. ---------------------------------------------------------------------- Martin_fr · 2022-10-22 18:35 Quote from: lazer on October 22, 2022, 05:54:43 pmHowever, the good news stops there. I can step into lpr file but breakpoints and run to cursor inside the pas file have no effect , it's just like a normal Run. Yet that pas file (in which breakpoint fail) has blue dots? And the breakpoint is on a line that has a blue dot? (well you will not see the blue dot, if the breakpoint is set, but if you un-set the breakpoint, then there should be a blue dot)? If breakpoints don't work "Run to cursor" will not either, because it just internally sets the breakpoint. (Though "run to cursor" will look for a blue-dot below, if the line itself does not have one / breakpoints only ever look at the exact line). - Before you start the debugger breakpoints should be a "red ball" with a question mark on it. - When the debugger runs, they should be a "red ball" with a "check- mark" on it. If the have any other color or symbol then please report. ---------------------------------------------------------------------- lazer · 2022-10-22 19:02 All is as you describe.