Recent

Author Topic: [solved] Gdb changes a parameter?  (Read 3776 times)

Joanna

  • Hero Member
  • *****
  • Posts: 1450
[solved] Gdb changes a parameter?
« on: March 11, 2024, 05:58:34 pm »
Hi everyone
I am curious about what is happening with certain code crashing when I step into it with the gdb in Lazarus ide.

My code has a
Code: Pascal  [Select][+][-]
  1. Myclass =class(tpanel)
  2. Procedure set_position (const avalue:integer);
  3. Function get_position:integer;
  4. Property position:integer read get_position write set_position
  5. End;
  6.  
  7. Procedure myclass.set_position (const avalue:integer);
  8. Begin
  9. Trackbar.position:= avalue;
  10. End;
  11.  
  12.  

When I call this I’m sending either max or min value of the trackbar. {Min= 1, max=100}
When I don’t step into it, it will set the position correctly.

However when I try to step into the code to set position property it crashes with an external sigsegv error in the set_position procedure. When I hover over the parameter going into the crashing procedure code it is some ridiculous number over 41 million when it should be 100.

My question is where did this erroneous value come from ?
Is gdb overwriting the value as step into and assign it to the property?

I’m using win 7, Lazarus 2.0.12
« Last Edit: March 12, 2024, 03:32:46 pm by Joanna »

Thaddy

  • Hero Member
  • *****
  • Posts: 19150
  • Glad to be alive.
Re: Gdb changes a parameter?
« Reply #1 on: March 11, 2024, 06:52:33 pm »
Your 41 million is probably a pointer.
objects are fine constructs. You can even initialize them with constructors.

rvk

  • Hero Member
  • *****
  • Posts: 7017
Re: Gdb changes a parameter?
« Reply #2 on: March 11, 2024, 07:08:24 pm »
However when I try to step into the code to set position property it crashes with an external sigsegv error in the set_position procedure.
And value doesn't really matter if you get a sigsegv.

Your trackbar is probably nil.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
Re: Gdb changes a parameter?
« Reply #3 on: March 11, 2024, 07:36:28 pm »
You are probably looking at 2 individual issues.

1) local variables on the "begin" line.

When you step into a function, you may land on the begin line (iirc, some gdb versions avoid that in some case for some functions...., but generally it's the begin line).
On the "begin" line local vars and parameters are not yet correctly visible to the debugger (that applies to all debuggers).

The reason for that is, that the calling convention may require values in registers, or on location on the stack that differ from the location used once in the function.
The debug info generated by fpc does not tell the debugger that it is in a register.

In pseudo code the "begin" line looks like this (extract of the parts that matter here).
- Allocate space on the stack (the so called "frame").
- Copy all parameters from registers (or other locations) into that space.

And the debugger is only told to look in the "frame" => so at the begin line, the debugger sees trash, that just happens to be there.


2) The crash...
Very hard to tell....
- Do you use Optimization level "none" or "1" ? (try "none")
- Does it change, if you change the order of your procedures in the implementation section?

It could be any amount of reasons.... IIRC some fpc (likely 3.2.2, but its a while since I looked at this) had a bug that would write info for the debugger in such a way, that certain gdb versions would expect the assembler in the wrong location => and then when gdb inserts a breakpoint (even an internal one, that you did not set) that breakpoint would crash the code.

But, it is hard to tell from the description. Could be easily something else.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
Re: Gdb changes a parameter?
« Reply #4 on: March 11, 2024, 07:40:22 pm »
I don't recall the state of FpDebug in 2.0.12...  May be an alternative.

The issue I mentioned: https://gitlab.com/freepascal.org/fpc/source/-/issues/39499  So that is fpc 3.3.1 and shouldn't affect you.

Joanna

  • Hero Member
  • *****
  • Posts: 1450
Re: Gdb changes a parameter?
« Reply #5 on: March 12, 2024, 01:48:12 am »
Thanks Martin
I have changed the optimization level from 1 to 0. When I step into it now instead of crashing it opens the assembler window.

I have often wondered about how stepping into things works... sometimes it seems to go to end of function  first then to the beginning so if I have breakpoint at end hoping to see result it is stopping there before result has been set.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
Re: Gdb changes a parameter?
« Reply #6 on: March 12, 2024, 10:04:50 am »
I have often wondered about how stepping into things works... sometimes it seems to go to end of function  first then to the beginning so if I have breakpoint at end hoping to see result it is stopping there before result has been set.

The going to the end is a bug in fpc. 

Pascal is translated into asm. Including implicit code like the setting up of the frame. Or, if you use local ansistrings, fpc inserts a hidden try/finally (into the begin/end lines).

Fpc writes a map, that shows for each asm statement to which line it belongs. And for some of the statements in the "setup" part, it writes the number of the "end" line. So the debugger then shows that.
I am not sure, but I think it's the optimizer (level 1), when it moves some asm code around.

Joanna

  • Hero Member
  • *****
  • Posts: 1450
Re: Gdb changes a parameter?
« Reply #7 on: March 12, 2024, 10:35:52 am »
Quote
The going to the end is a bug in fpc. 

Pascal is translated into asm. Including implicit code like the setting up of the frame. Or, if you use local ansistrings, fpc inserts a hidden try/finally (into the begin/end lines).

I hope that bug is fixed someday..
I never knew there was a hidden try/finally in there. What errors is it trying to catch?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
Re: Gdb changes a parameter?
« Reply #8 on: March 12, 2024, 10:40:12 am »
I never knew there was a hidden try/finally in there. What errors is it trying to catch?
Memory leaks for ansistring, dynarray and other refcounted types.
Code: Pascal  [Select][+][-]
  1. procedure foo;
  2. var a: ansistring;
  3. begin
  4.   a:=getText;
  5.   DoFooAndRaiseException;
  6. end;

When "a" goes out of scope, the refcount of the string needs to be decremented. Even if there is an exception.

https://www.freepascal.org/docs-html/prog/progsu34.html#x41-400001.2.34

Joanna

  • Hero Member
  • *****
  • Posts: 1450
Re: Gdb changes a parameter?
« Reply #9 on: March 12, 2024, 10:59:19 am »
So if you have a procedure with local variable is it allocated and de allocated as you enter and exit the method ? What happens with a procedure with static method? How does that work?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
Re: Gdb changes a parameter?
« Reply #10 on: March 12, 2024, 12:26:32 pm »
So if you have a procedure with local variable is it allocated and de allocated as you enter and exit the method ? What happens with a procedure with static method? How does that work?
you mean static variable? Just a global var, with limit scope for access.

Joanna

  • Hero Member
  • *****
  • Posts: 1450
Re: Gdb changes a parameter?
« Reply #11 on: March 12, 2024, 03:07:42 pm »
I never thought of a static variable inside a procedure as global before.
I assumed that global variables were accessible from everywhere.
How is access to it prevented outside the scope of the procedure in which it is declared?

440bx

  • Hero Member
  • *****
  • Posts: 6488
Re: Gdb changes a parameter?
« Reply #12 on: March 12, 2024, 03:42:28 pm »
How is access to it prevented outside the scope of the procedure in which it is declared?
It is prevented by having the compiler _not_ acknowledge the existence of the variable outside the function/procedure.  That's the same reason why variables that are local to a function/procedure cannot be accessed from another function/procedure, it's because outside that scope the compiler doesn't "see" the variable.

However, in the case of a static variable, a dirty trick can be implemented to make the variable accessible outside the function's/procedure's scope.  The trick is to have the function/procedure where the variable is defined somehow return a pointer to it.  Any function/procedure that obtains a pointer to it can then change it (because it "sees" it by virtue of the pointer to it.)  That "trick" could also be used to obtain the address of local variable but, that's futile because once the function/procedure returns that memory will be used by something else making having a pointer to it completely useless.

HTH.


FPC v3.2.2 and Lazarus v4.0rc3 on Windows 7 SP1 64bit.

Joanna

  • Hero Member
  • *****
  • Posts: 1450
Re: [solved] Gdb changes a parameter?
« Reply #13 on: March 12, 2024, 03:53:40 pm »
Thanks for explanation.

MarkMLl

  • Hero Member
  • *****
  • Posts: 8572
Re: Gdb changes a parameter?
« Reply #14 on: March 13, 2024, 10:11:25 am »
I never thought of a static variable inside a procedure as global before.
I assumed that global variables were accessible from everywhere.
How is access to it prevented outside the scope of the procedure in which it is declared?

You've got two things there: scope and visibility. I think it might be useful if we depart from "computers as currently taught" and consider them separately.

For the sake of explanation, let's assume that global variables are all on the heap, i.e. are allocated when the main block starts and left there.

Global variables are at the outermost scope, and are permanently visible unless hidden by a "nearer" declared name.

Variables which are allocated on the stack as you go deeper into nested functions are in scope, but might not be visible if their names are hidden by a "nearer" declaration.

Static (i.e. const something) variables are at least in effect put on the heap when their declaration is first encountered. From that point onwards their value is retained, but they're only visible inside the function where they're declared even though their scope could be considered as similar to globals.

If anything, it is those scope and visibility rules which define an ALGOL-derived language: details like begin/end vs { } are much less significant.

Usually, texts lump scope and visibility together these days because C, as the dominant ALGOL derivative, makes little distinction between them.

Rust departs from that, and is much more aggressive at removing visibility in cases where the compiler decides that leaving a variable visible is unsafe. Its popularity is largely derived from extending the principles that Wirth defined 50 years ago, and which have been largely forgotten as his languages have fallen into obscurity: however its departure from ALGOL's scope and visibility rules suggest to me at least that it should not be considered an ALGOL-derivative.

At this point it's also worth mentioning Cowgol http://cowlark.com/cowgol/index.html which as a very small language with strict typing etc. is possibly the closest to Wirth's original intention.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018