Recent

Author Topic: Locals window shows <error reading variable> for all locals  (Read 452 times)

440bx

  • Hero Member
  • *****
  • Posts: 1122
Hello,

For some reason, the debugger "locals" window shows "<error reading variable> for all the function/procedure locals (using GDB as it was originally installed by the Lazarus install program).  There is nothing unusual about the functions/procedures.

It didn't use to do that.  When it first happened a while back, I simply thought there was something in that particular program it didn't like and worked around it.  Now it seems to happen all the time.

If I right click on any of the local variables and select "watch", that works fine. 

Is there something that should be "reset"/"changed" in my Lazarus installation that would make the locals window work again ?  Ideas and suggestions, appreciated.

Thank you for your help.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5621
    • wiki
Re: Locals window shows <error reading variable> for all locals
« Reply #1 on: May 04, 2019, 05:40:24 pm »
Just to be sure, you stepped past the "begin" line? On the begin (begin of procedure) line, this may happen.
Also, you do not have optimizations enabled? Opt = 0.

64bit IDE and 64 bit project?
Not related to nested procedures?
Do the variables work, if you add them to the watches window?

Please either provide a log
http://wiki.lazarus.freepascal.org/GDB_Debugger_Tips#Log_info_for_debug_session

Or the entire output of: View > Ide Internals > Debug Output
(Please make sure you do open that window before you start debugging.)

Please provide a sample of the var declaration of such a method.

440bx

  • Hero Member
  • *****
  • Posts: 1122
Re: Locals window shows <error reading variable> for all locals
« Reply #2 on: May 04, 2019, 07:57:02 pm »
Just to be sure, you stepped past the "begin" line?
yes, definitely.  :)

Also, you do not have optimizations enabled? Opt = 0.
I was using the "debug" build mode which has O1.  To determine if that made a difference, I changed it to 0 and still got the <error reading variable> for all the locals.

64bit IDE and 64 bit project?
32bit IDE producing a 32bit executable running on Win7 64bit.

Not related to nested procedures?
No nested procedures anywhere in the program.

Do the variables work, if you add them to the watches window?
Yes!.  I can add any of the locals that produced an <error reading variable> and they show just fine.

Please either provide a log
http://wiki.lazarus.freepascal.org/GDB_Debugger_Tips#Log_info_for_debug_session
Attached the compressed log to this post.

Or the entire output of: View > Ide Internals > Debug Output
(Please make sure you do open that window before you start debugging.)
Done almost exactly as you requested.  The log is obtained from View > Debug Windows > Debug Output, which is what I believe you meant.


Please provide a sample of the var declaration of such a method.
Code: Pascal  [Select]
  1. function WndProc (Wnd : hWnd; Msg : UINT; wParam, lParam : ptrint)
  2.          : ptrint; stdcall;
  3.   { main application/window handler function                                  }
  4. const
  5.   ConhostProcesses   = 'conhost.exe process list';
  6.  
  7.   ListBox       : HWND  =  0;
  8.  
  9.   ID_LISTBOX            = 1000;
  10.   ID_STATWIN            = 2000;
  11.  
  12.   Visible       : pchar = nil;
  13.  
  14.   Bitness       : pchar = nil;
  15.  
  16.   {---------------------------------------------------------------------------}
  17.  
  18.   ListboxHeader = 'Window handle    Process Id    Thread Id    V(isible)  '   +
  19.                   'Executable name';
  20.  
  21.   EMPTY_STRING  : pchar = #0;
  22.  
  23.   {---------------------------------------------------------------------------}
  24.  
  25.   VisibleYes            = 'V';
  26.   VisibleNo             = ' ';
  27.  
  28.   Bitness32             = '_32_';
  29.   Bitness64             = ' 64 ';
  30.   BitnessUnknown        = '    ';
  31.  
  32.   ProcessList           : PProcessList = nil;
  33.   ConsoleList           : PConsoleList = nil;
  34.   ConhostList           : PConhostList = nil;
  35.  
  36. var
  37.   ClientRect            : TRECT;
  38.   StatRect              : TRECT;
  39.   Style                 : ptruint;
  40.  
  41.   StatWnd               : HWND;
  42.  
  43.   i                     : TConsoleListRange;
  44.  
  45. begin
  46.   WndProc := 0;
  47.  
  48.   case Msg of
  49.     WM_CREATE:
  50.     begin
  51.       {$ifdef DEBUG}
  52.         if IsDebuggerPresent() then DebugBreak();
  53.       {$endif}
  54.  
  55.       { allocate memory for the list of conhost processes                     }
  56.  
  57.       ConsoleList := HeapAlloc(GetProcessHeap(),
  58.                                HEAP_ZERO_MEMORY,
  59.                                sizeof(ConsoleList^));
  60.  
  61.       if ConsoleList = nil then
  62.  
It's not a method (I don't have any of those) just the typical WndProc that handles window messages.  A breakpoint is/was set at the statement "ConsoleList := HeapAlloc...".

While preparing this for you, I noticed something that is probably very important.  The problem occurs only when the executable is 32bit.  If the executable is 64bit, the locals show just fine.

Maybe the problem is in GDB and not in Lazarus but, if that is the case, what I don't understand is why it used to work.

Now that I've realized the problem only occurs in 64bit, it is not that much of an issue for me since the final version is always 64bit.  I only use the 32bit target to ensure the program works in both bitnesses.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5621
    • wiki
Re: Locals window shows <error reading variable> for all locals
« Reply #3 on: May 04, 2019, 08:51:17 pm »
The Log is all good. Nothing that would indicate an incorrect setting in the IDE.

It is beyond strange that gdb has issues getting the values as locals, but can do them as watch. Especially for basic types like HWnd (which in the end is just an int or cardinal...)

It even gets the values, with the threads and stackframes (for thread and stack window), which is very similar to the local data.

To me it looks like a bug in gdb. But not sure what triggers it.
Between successfully getting it for stack/thread and then failing for locals, the only thing happening is getting the disassembler.

Are you using dwarf or stabs? It looks like stabs (Project > Project Options > Debugging: Debug information type).
I do highly recommend to use "dwarf (with sets)".
Does it make a difference?
(If you debug in packages, you may need to change it for each package too.)


As for the issue (if dwarf does not help), I would recommend to try one of the alternative debuggers
https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2032%20bits/Alternative%20GDB/

I have no test results for Win 7.
On Windows 10, all tests show that 8.2 is good. (And I am planing to change to it for the next major release, i.e., 2.2.0)

I would expect it to be fine on Win7 too.

If you for any reason want to use "stabs", then you should go with GDB 7.7.1.





It is (remotely) possible that a recent Windows update could have caused changes. For once cross debugging (Bitness of IDE and app differ) lost the ability to pause the debugged app (fixed in trunk / But that fix would not help you).  Some people reported running in compatibility mode helped them.

I don't however see, how that could cause the observed inconsistency in gdb....



I also noted you do receive a strange
Code: Pascal  [Select]
  1. stopped,reason="signal-received
For which I found no reason.
Maybe try DissableLoadSymbolForLibraries in the Tools > Option > Debugger

But that seems otherwise unrelated to the issue



I hope some of this will help

440bx

  • Hero Member
  • *****
  • Posts: 1122
Re: Locals window shows <error reading variable> for all locals
« Reply #4 on: May 04, 2019, 10:10:40 pm »
I hope some of this will help
Before anything, I have to say, your explanation was thorough, detailed and accurate.  You really do great work.  Thank you.

It is beyond strange that gdb has issues getting the values as locals, but can do them as watch. Especially for basic types like HWnd (which in the end is just an int or cardinal...)

It even gets the values, with the threads and stackframes (for thread and stack window), which is very similar to the local data.
I agree.  I found it puzzling too.

Are you using dwarf or stabs? It looks like stabs (Project > Project Options > Debugging: Debug information type).
I do highly recommend to use "dwarf (with sets)".
Does it make a difference?
(If you debug in packages, you may need to change it for each package too.)
That was the magic question.  It was set to "automatic".  I never gave that a second thought, it seemed to work fine.  I checked the executable and it was using stabs.  I changed it to "dwarf (with sets)" and ... problem solved.  The locals are there.  That is great.    It also explains why thngs worked when compiling for a 64bit target and didn't work for a 32bit target.  As I am sure you know, when compiling for a 64bit target, the debug info is dwarf, not stabs.

As for the issue (if dwarf does not help), I would recommend to try one of the alternative debuggers
https://sourceforge.net/projects/lazarus/files/Lazarus%20Windows%2032%20bits/Alternative%20GDB/
Fortunately and, thanks to you, I won't need to go that route.

If you for any reason want to use "stabs", then you should go with GDB 7.7.1.
I don't have any.  I just want to use what works.  Simplicity is good. :)

It is (remotely) possible that a recent Windows update could have caused changes.
I disable Windows updates.  That thing is nothing but headaches.  First thing I do in a Windows installation, ensure there will be no updates.  I wish I could do that with VS2017, another source of headaches.

I also noted you do receive a strange
Code: Pascal  [Select]
  1. stopped,reason="signal-received
For which I found no reason.
This is a guess but, it may be because I have conditional calls to DebugBreak() sprinkled in the code.  I'm guessing GDB considers that a signal.

The problem is solved.  Thank again Martin.  Very nicely done.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.