Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2015-03

BreakIf

15 messages · 7 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

JuuS

Good morning, all...

From my Delphi days we had the following procedure:
procedure BreakIf( b : Boolean );
begin
 if b then
 asm
   INT 3    <======debugger would then stop here
            and one could then F8 step to the offending
            routine based on the boolean condition passed
 end;
end;

I believe this is windows specific (?) and I'm now working on Linux machines.

The question is:

This does not work in Linux and I wonder if there is a similar way to achieve this in Linux environment?

It's like making an on-the-fly breakpoint, and was amazingly useful. This was a really good way to debug loops and for/do's simply and effectively. Would be nice to have it in my current environment too...if possible.

Julius

Reply by email

Joost van der Sluis
to JuuS
JuuS wrote 17 lines
procedure BreakIf( b : Boolean ); begin if b then asm INT 3 <======debugger would then stop here and one could then F8 step to the offending routine based on the boolean condition passed end; end; I believe this is windows specific (?) and I'm now working on Linux machines. The question is: This does not work in Linux and I wonder if there is a similar way to achieve this in Linux environment?

Wow.. that's a nasty trick....

And it should still work, also on Linux.

But I think that debuggers nowadays are more clever, they detect that the breakpoint is actually self-inflicted, and so they decide to continue. After all: the developer can have it's reasons to call this interrupt, and the debugger should not influence normal execution.

I don't know if fpdebug has this same check. (I think it has, though, but I'm not sure) If you are using a development Lazarus version you can try to install the LazDebuggerFp package, and choose the 'Fpdebug internal Dwarf-debugger' as debugger in the debugger-options. See what happens if you do that...

Regards,

Joost.

Reply by email

JuuS
to Joost van der Sluis
Joost van der Sluis wrote 20 lines
On 03/27/2015 01:45 PM, JuuS wrote: > procedure BreakIf( b : Boolean ); > begin > if b then > asm > INT 3 <======debugger would then stop here > and one could then F8 step to the offending > routine based on the boolean condition passed > end; > end; > > I believe this is windows specific (?) and I'm now working on Linux > machines. > > The question is: > > This does not work in Linux and I wonder if there is a similar way to > achieve this in Linux environment? Wow.. that's a nasty trick....

Mmmm, nasty maybe...but cool! Just tried it again and it won't compile "INT 3" line because "invalid reference syntax".

I will look into your suggestions in the next days and report back if I find anything, thanks Joost.

Show quoted text 23 lines
And it should still work, also on Linux. But I think that debuggers nowadays are more clever, they detect that the breakpoint is actually self-inflicted, and so they decide to continue. After all: the developer can have it's reasons to call this interrupt, and the debugger should not influence normal execution. I don't know if fpdebug has this same check. (I think it has, though, but I'm not sure) If you are using a development Lazarus version you can try to install the LazDebuggerFp package, and choose the 'Fpdebug internal Dwarf-debugger' as debugger in the debugger-options. See what happens if you do that... Regards, Joost. -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Sven Barth
to JuuS
"JuuS" wrote 27 lines
On 03/27/2015 02:17 PM, Joost van der Sluis wrote: > On 03/27/2015 01:45 PM, JuuS wrote: >> procedure BreakIf( b : Boolean ); >> begin >> if b then >> asm >> INT 3 <======debugger would then stop here >> and one could then F8 step to the offending >> routine based on the boolean condition passed >> end; >> end; >> >> I believe this is windows specific (?) and I'm now working on Linux >> machines. >> >> The question is: >> >> This does not work in Linux and I wonder if there is a similar way to >> achieve this in Linux environment? > > Wow.. that's a nasty trick.... Mmmm, nasty maybe...but cool! Just tried it again and it won't compile "INT 3" line because "invalid reference syntax".

You need to write either "INT $3" or switch the assembler syntax to Intel ({$asmmode intel}) as the default one is AT&T on Linux.

Please note that INT 3 is specific to x86 (and will likely also work on x86_64), but for other architectures you'll need to look up their specific breakpoint sequences.

Please state beforehand next time whether you can't compile or can't run. We have no crystal balls after all...

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20150327/400cac12/attachment.html>

Reply by email

Sven Barth
to Joost van der Sluis: Wow.. that's a nasty trick.... And it should still work, also on Linux. But I think that…
"Joost van der Sluis" wrote 27 lines
On 03/27/2015 01:45 PM, JuuS wrote: > > procedure BreakIf( b : Boolean ); > begin > if b then > asm > INT 3 <======debugger would then stop here > and one could then F8 step to the offending > routine based on the boolean condition passed > end; > end; > > I believe this is windows specific (?) and I'm now working on Linux > machines. > > The question is: > > This does not work in Linux and I wonder if there is a similar way to > achieve this in Linux environment? Wow.. that's a nasty trick.... And it should still work, also on Linux. But I think that debuggers nowadays are more clever, they detect that the

breakpoint is actually self-inflicted, and so they decide to continue. After all: the developer can have it's reasons to call this interrupt, and the debugger should not influence normal execution.

This might be true on an embedded system, but if you run any of the normal OSes where you can't modify interrupt handlers anyway then on x86(_64) INT 3 (or $CC) /always/ means breakpoint. And from experience I know that both GDB and WinDBG respect these as they should.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20150327/b04f7ef4/attachment.html>

Reply by email

JuuS
to Sven Barth: You need to write either "INT $3" or switch the assembler syntax to Intel ({$asmmode…
Sven Barth wrote 33 lines
Am 27.03.2015 14:32 schrieb "JuuS" < <mailto:>>: > > > > On 03/27/2015 02:17 PM, Joost van der Sluis wrote: > > On 03/27/2015 01:45 PM, JuuS wrote: > >> procedure BreakIf( b : Boolean ); > >> begin > >> if b then > >> asm > >> INT 3 <======debugger would then stop here > >> and one could then F8 step to the offending > >> routine based on the boolean condition passed > >> end; > >> end; > >> > >> I believe this is windows specific (?) and I'm now working on Linux > >> machines. > >> > >> The question is: > >> > >> This does not work in Linux and I wonder if there is a similar way to > >> achieve this in Linux environment? > > > > Wow.. that's a nasty trick.... > > Mmmm, nasty maybe...but cool! Just tried it again and it won't compile > "INT 3" line because "invalid reference syntax". You need to write either "INT $3" or switch the assembler syntax to Intel ({$asmmode intel}) as the default one is AT&T on Linux.

Awesome. It works! I have no idea about assembler and had no clue about this syntax, my breakif code came from a windows environment.

It does raise a "SIGTRAP" message in the IDE which must be dealt with but I can live with this (though ideas to suppress it appreciated).

Thanks Sven. (I will still look into the other stuff as time permits Giuliano).

It's nice to have this back for when I really need it.

Show quoted text 6 lines
Please note that INT 3 is specific to x86 (and will likely also work on x86_64), but for other architectures you'll need to look up their specific breakpoint sequences. Please state beforehand next time whether you can't compile or can't run. We have no crystal balls after all...

I came into Lazarus about a year ago, that's when I tested breakif and it failed and that was all I remembered. Had no idea of the Lazarus mailing list at that time and only today was thinking about it again. Will do my utmost to be more proactive next time.

Show quoted text 12 lines
Regards, Sven -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Henry Vermaak
to JuuS: Good morning, all... procedure BreakIf( b : Boolean ); begin if b then asm INT 3 …
JuuS wrote 16 lines
Good morning, all... >From my Delphi days we had the following procedure: procedure BreakIf( b : Boolean ); begin if b then asm INT 3 <======debugger would then stop here and one could then F8 step to the offending routine based on the boolean condition passed end; end; I believe this is windows specific (?) and I'm now working on Linux machines.

On Windows you can use DebugBreak() instead of the asm.

The question is: This does not work in Linux and I wonder if there is a similar way to achieve this in Linux environment?

To be more portable, you can send the SIGTRAP signal, just make sure that your program ignores it so it doesn't die. Try this with/without GDB:

program bp;
uses BaseUnix;
begin
	FpSignal(SIGTRAP, signalhandler_t(SIG_IGN));
	writeln('hi there');
	FpKill(FpGetpid, SIGTRAP); { <-- breakpoint here }
	writeln('exiting');
end.

Henry

Reply by email

Marc Weustink
to Joost van der Sluis: Wow.. that's a nasty trick.... And it should still work, also on Linux. But I think that…
Joost van der Sluis wrote 33 lines
On 03/27/2015 01:45 PM, JuuS wrote: > procedure BreakIf( b : Boolean ); > begin > if b then > asm > INT 3 <======debugger would then stop here > and one could then F8 step to the offending > routine based on the boolean condition passed > end; > end; > > I believe this is windows specific (?) and I'm now working on Linux > machines. > > The question is: > > This does not work in Linux and I wonder if there is a similar way to > achieve this in Linux environment? Wow.. that's a nasty trick.... And it should still work, also on Linux. But I think that debuggers nowadays are more clever, they detect that the breakpoint is actually self-inflicted, and so they decide to continue. After all: the developer can have it's reasons to call this interrupt, and the debugger should not influence normal execution. I don't know if fpdebug has this same check. (I think it has, though, but I'm not sure) If you are using a development Lazarus version you can try to install the LazDebuggerFp package, and choose the 'Fpdebug internal Dwarf-debugger' as debugger in the debugger-options. See what happens if you do that...

when setting a BP, (the original) fpdebug checks if location of the BP already has a INT3 (not sure about INT 3). In that case it doesn't insert a new one, it only records it.
So fpdebug is aware of coded breakpoints. when it hits a coded BP, it stops execution (and might raise a SIGTRAP)

Marc

Reply by email

JuuS
to Henry Vermaak: On Windows you can use DebugBreak() instead of the asm. To be more portable, you can send…
Henry Vermaak wrote 37 lines
On Fri, Mar 27, 2015 at 01:45:31PM +0100, JuuS wrote: > Good morning, all... > > >From my Delphi days we had the following procedure: > > procedure BreakIf( b : Boolean ); > begin > if b then > asm > INT 3 <======debugger would then stop here > and one could then F8 step to the offending > routine based on the boolean condition passed > end; > end; > > I believe this is windows specific (?) and I'm now working on Linux > machines. On Windows you can use DebugBreak() instead of the asm. > The question is: > > This does not work in Linux and I wonder if there is a similar way to > achieve this in Linux environment? To be more portable, you can send the SIGTRAP signal, just make sure that your program ignores it so it doesn't die. Try this with/without GDB: program bp; uses BaseUnix; begin FpSignal(SIGTRAP, signalhandler_t(SIG_IGN)); writeln('hi there'); FpKill(FpGetpid, SIGTRAP); { <-- breakpoint here } writeln('exiting'); end.

Super, thanks Henry, this also works, started the day with no breakif, end up with several. Greatly appreciated.

Show quoted text 8 lines
Henry -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply by email

Joost van der Sluis
to Sven Barth: breakpoint is actually self-inflicted, and so they decide to continue. After all: the…
Sven Barth wrote 11 lines
Am 27.03.2015 14:17 schrieb "Joost van der Sluis" < <mailto:>>: > But I think that debuggers nowadays are more clever, they detect that the breakpoint is actually self-inflicted, and so they decide to continue. After all: the developer can have it's reasons to call this interrupt, and the debugger should not influence normal execution. This might be true on an embedded system, but if you run any of the normal OSes where you can't modify interrupt handlers anyway then on x86(_64) INT 3 (or $CC) /always/ means breakpoint. And from experience I know that both GDB and WinDBG respect these as they should.

It should result in a sigtrap (it *IS* a sigtrap), and the debugger can stop on those. But that's something else than the debugger report a stop at a breakpoint.

Joost.

Reply by email

Graeme Geldenhuys
to JuuS: Good morning, all... procedure BreakIf( b : Boolean ); begin if b then asm INT 3 …
JuuS wrote
Would be nice to have it in my current environment too...if possible.

There is a simple solution indeed. The following works on all platforms and will give the same result as your BreakIf() did.

"
var
testvar: integer;
[...]
if b then
testvar:= 0; //<<<--- set a breakpoint here
"
In order to remove the test statements use "testvar" in 'Search'-'Find in Files'-'Text to find'.

I use this work-around because Condition Breakpoints still ain't fully implemented in Lazarus IDE or MSEide.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Martin Schreiber
to Graeme Geldenhuys
Graeme Geldenhuys wrote 6 lines
On 2015-03-27 12:45, JuuS wrote: I use this work-around because Condition Breakpoints still ain't fully implemented in Lazarus IDE or MSEide.

They *are* implemented. The problem you probably refer to is that gdb uses the pointer values instead of the text for string comparisons. What I fear more is that the FPC-gdb combination can not show class fields anymore.
http://wiki.lazarus.freepascal.org/GDB_Debugger_Tips#Bugs_in_GDB https://sourceware.org/bugzilla/show_bug.cgi?id=17835 The problem still exists in gdb 7.9.0. Possible workarounds are sub-optimal specifically for multi-language IDEs.

Martin

Reply by email

Graeme Geldenhuys
to Martin Schreiber
Martin Schreiber wrote
They *are* implemented. The problem you probably refer to is that gdb uses the pointer values instead of the text for string comparisons.

Correct. Compared to what I can do with Delphi or Kylix - most of those Condition Breakpoint cases simply aren't possible with Lazarus IDE or MSEide.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

JuuS
to Graeme Geldenhuys: There is a simple solution indeed. The following works on all platforms and will give the…
Graeme Geldenhuys wrote 15 lines
On 2015-03-27 12:45, JuuS wrote: > Would be nice to have it in my current environment too...if > possible. There is a simple solution indeed. The following works on all platforms and will give the same result as your BreakIf() did. " var testvar: integer; [...] if b then testvar:= 0; //<<<--- set a breakpoint here "

D'oh! Good one. This is one of those "why didn't I think of that" moments...

Show quoted text 11 lines
In order to remove the test statements use "testvar" in 'Search'-'Find in Files'-'Text to find'. I use this work-around because Condition Breakpoints still ain't fully implemented in Lazarus IDE or MSEide. Regards, - Graeme -

Reply by email

Graeme Geldenhuys
to JuuS
JuuS wrote
D'oh! Good one. This is one of those "why didn't I think of that" moments...

:-) Don't worry the same happened to me a couple weeks back. Credit must be given to Martin Schreiber for pointing out the obvious solution.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email