View Issue Details

IDProjectCategoryView StatusLast Update
0019262LazarusDebuggerpublic2011-12-01 11:26
ReporterH.HartlAssigned ToMartin Friebe 
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Platformi386OSOSXOS Version10.6
Product Version0.9.31 (SVN)Product Build30506 
Target VersionFixed in Version0.9.31 (SVN) 
Summary0019262: Debugger unusable / lazarus crash
DescriptionLazarus cant be quit / debugger is unusable.

Problem seems to be that the gdb interface expects a EXCEPTION object.
Steps To ReproduceUse:

program test;
{$mode objfpc}{$H+}
uses
  Sysutils,Classes;
//type
// ex = class(Exception)
// end;

begin
  writeln('set break point here');
end.

When definig the exception the debugger stops the console program.
Without the defined exception it runs into timeouts / does not react.
TagsNo tags attached.
Fixed in Revision30508
LazTarget0.99.0
WidgetsetCarbon
Attached Files

Activities

Martin Friebe

2011-04-29 13:51

manager   ~0047904

The debugger should attempt to use the exception object, if an exception occurs. And if not present, it has fall-backs to do the work without the object. (Or at least is should...)

On Mac OS (at least if using a 64 bit CPU) however certain (valid) gdb commands cause troubles. See http://wiki.lazarus.freepascal.org/GDB_Debugger_Tips#Debug_session_freezes

Please provide the following:

- Which architecture to you have? Intel? 32 or 64 bit?

- Open the "Debug output" window (from menu "View", "Debug windows"). Do open this before you try to run your app. Run your app, once the error occurs, copy, zip, and attach the content of the "debug output" window

- Start lazarus from a shell with -debug-log option (you can do this for the same run as above):
/path/to/lazarus/lazarus.app/Content/MacOS/lazarus --debug-log=/path/to/yourfiles/laz.log
Attach the log file after reproducing the error.

If possible, before producing the log file, please recompile the IDE with:
-dDBG_VERBOSE -dDBGMI_QUEUE_DEBUG

Thank you

2011-04-29 14:43

 

logs.zip (5,133 bytes)

H.Hartl

2011-04-29 14:43

reporter   ~0047905

Hmm - when using gdb directly the difference is that ptype EXCEPTION gives an undefined result in the bad case.

I am using a 64 Bit Core i7 on a MBP 17'' early 2011. (Snow Leopard 10.6.7)
Lazarus is a 32 Bit/Carbon executable.
(to my knowledge no 64 bit lazarus/carbon edition is possible on darwin)

If recompiled the IDE with that defines and I attach the logs.

HTH and thanks

Martin Friebe

2011-04-29 16:26

manager   ~0047907

Last edited: 2011-04-29 16:33

Thanks for the log.
In revision 30508:

I have added time-outs to the relevant ptype at debugger start-up (all other ptype are in watches, and should have time-outs already)

I have added an option (Tools/Option/Debugger) to disable the warning at each time-out.
I also added a log entry to the "event-log" (debugger windows) for each time-out.

And I added more checks to detect the command state after a time-out.

---
Only, I have no possibility to test this myself, since none of my systems ever had the issue (it's 64 bit Mac only).

So I would be grateful if you could test all of the changes (and if further error occur, supply a new set of log files):

- Does it work at all now?
- Do Time-out warning dialogs show (or not) according to the setting in the options?
- Do Time-outs always (independent of the options) show in the event-log? (Actually that depends on the "Event Log settings in the Tools/Options dialog. In the list of "Messages", the entry "Debugger" must be checked)

Thanks for the feedback

And last, but not least, if it works, could you still supply a console log file? I'd like to see which of the ptype at start-up actually work (with an such an empty app)

2011-05-01 01:37

 

logs2.zip (28,011 bytes)

H.Hartl

2011-05-01 01:40

reporter   ~0047941

First of all - this is a major improvement.
Setting timeout to 250 and warnings off is workable. :-)

It seems that the debugger runs into a timeout when evaluating
an "unknown" symbol.

Given:

program project1;
{$mode objfpc}{$H+}
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes,sysutils
  { you can add units after this };
//type ex=class(exception) end;
{$R *.res}
var i:integer;
begin
  for i:=0 to 2 do begin
    writeln('TEST ',i);
  end;
end.

Without exception definition it takes (250ms timeout) around 2 seconds to
hit a breakpoint on the for i=0 line.
With the aforementioned "type ex=class(Exception) end;" enhancement
startup is immediate.
With 5000ms TO it takes more then 10 seconds (!).
On mouseover on the writeln symbol (yields a hint with writeln=???)
It takes under a second (250ms TO) to evaluate i right after a
TO on a writeln eval. (again with mouseover).
With 5000ms TO it takes many seconds.

But thats far better then before because one eval of an unknown symbol
produced a full debugger crash.

This observation leads me to the wild speculation that after lazarus runs
into the first TO gdb responds again fast.
(because the behaviour is much better with shorter timeouts).
Maybe the command is not finished for gdb for some reason,
so that gdb waits (and lazarus too ?), and they get in sync
again after the retry ?

Anyway big thanks and I'll post my logs again.

Martin Friebe

2011-05-01 12:43

manager   ~0047944

About the new log: Was that a successful run? it seems to stop after the initial "ptype TObject"; but on success there should be a bunch of other ptype (Exception, pointer shortstring, byte, char). It's the IDE's way to find out what types it can later use.

About the time out. Yes I know it is a slowdown. And the value in the config is misleading, the real waiting time is higher..

Anyway about the timeout.
Gdb is normally responding as follows:
- optional echo of statement, warnings, log messages. All prefixed by certaiin chars, so they can be regocnized.
- One result. Again prefixed (by ^)
- the prompt

In the case of those "broken" commands, neither result nor prompt are returned by GDB.
As for why is unknown. Maybe GDB encounters some internal error? Experienced showed that GDB functions normal afterwards.That means it does not seem to have taken any damage (like mem corruption), that will later lead to errors. But there is no proof that not any later problems could arise from having gone through a time out issue.
A previous timeout does not affect the problem re-occuring on the next problematic command.

The problem is that the IDE expects this one result per command, and uses the prompt to know what the output for the command is finished.
The IDE has currently no other way to synchronize the results with the commands it did send.
Hence the long timeout value.
If the IDE assumed a timeout, and the result coame later, the result would be attributed to the next command (and all results would be shifted that way).
Of course the next command would not recognize the result-format, or if it would it would use the wrong value.
For the IDE to skip the command's result, it must be 100% sure, the result really isn't there. Otherwise it screws the entire debug session.

To ensure that the IDE sends a 2nd command (that is known to work: "-data-evaluate-expression 7", if the IDE believes there is a timeout.
The IDE reads this result, and compares it against it's expectation.

But the IDE can not know if the original result may have returned the same value. So the IDE waits another (none configurable) 500 msec, to make sure no further result is received.

On the long run the IDE could learn to use the echo of the commands to verify what happens.

Now on a fast computer, that has no other load at all, you could probably quite safely have both timeout values set to 50, maybe less.

But the code must run on a slow PC too, there may be other load too. and maybe heavy use of a swap file, slowing the debug app down a lot.
So that is why values are that high at current.
I may commit slightly lower values, maybe 150 for the first, and 250 for the 2nd).
After all, the 1st value only initiates the sending of the 2nd test command, so it isn't 2 dangerous. The 2nd value applies only if a result was received after the test command:
- the test command times out after 1 second. If it does not deliver at least one result (the original, or it's own), the the session is broken, and will not be continued. This 1 second timeout does not matter. It only occurs if the session is to be killed anyway...
- if after the test command a result was received (without timeout, most often immediately), the 2nd timeout applies to ensure the 2nd result (if indeed any) will be read.

-----
Anyway since the issue is "fixed" (that is it does no longer hang) I will close this bug.
As for optimizing the behavior (as far a possible, there always will be some problem), I am aware of it.

For further discussion I am on the forum, the mailing list, or if required personal mail

Issue History

Date Modified Username Field Change
2011-04-29 13:05 H.Hartl New Issue
2011-04-29 13:05 H.Hartl Status new => assigned
2011-04-29 13:05 H.Hartl Assigned To => Marc Weustink
2011-04-29 13:51 Martin Friebe LazTarget => -
2011-04-29 13:51 Martin Friebe Note Added: 0047904
2011-04-29 13:51 Martin Friebe Assigned To Marc Weustink => Martin Friebe
2011-04-29 13:51 Martin Friebe Status assigned => feedback
2011-04-29 14:43 H.Hartl File Added: logs.zip
2011-04-29 14:43 H.Hartl Note Added: 0047905
2011-04-29 16:26 Martin Friebe Note Added: 0047907
2011-04-29 16:33 Martin Friebe Note Edited: 0047907
2011-05-01 01:37 H.Hartl File Added: logs2.zip
2011-05-01 01:40 H.Hartl Note Added: 0047941
2011-05-01 12:43 Martin Friebe Note Added: 0047944
2011-05-01 12:44 Martin Friebe Fixed in Revision => 30508
2011-05-01 12:44 Martin Friebe LazTarget - => 0.99.0
2011-05-01 12:44 Martin Friebe Widgetset => Carbon
2011-05-01 12:44 Martin Friebe Status feedback => resolved
2011-05-01 12:44 Martin Friebe Fixed in Version => 0.9.31 (SVN)
2011-05-01 12:44 Martin Friebe Resolution open => fixed
2011-05-01 12:44 Martin Friebe Target Version => 0.99.0
2011-12-01 11:26 Marc Weustink Status resolved => closed