Recent

Author Topic: Very Weird SIGSEGV  (Read 3653 times)

rwebb616

  • Full Member
  • ***
  • Posts: 133
Very Weird SIGSEGV
« on: April 19, 2021, 08:08:11 am »
I really hate inexplicable things... I have these two lines of code:

Code: Pascal  [Select][+][-]
  1.   setlabel('TitleLine1', 'Team ' + gameplay.starting.tostring, 80, 1);
  2.   setlabel('TitleLine2', 'Choose a Category:', 80, 2);


It goes through and executes the first line of code just fine... but then SIGSEGVs on the second one.  So I comment it out and further down in the block it makes several more calls to the setlabel function and all of those work just fine.  So I decide to move those two lines right below a block that creates and sets up a TPanel on my form - nothing special just sets a bunch of properties on it. 

Run the program - no crash.  I didn't change anything in the lines.. all I did was just simply move them below another piece of code and it works! 

Some people will be saying "Why are you writing on the forum then if your code is working?" ... as I said I hate inexplicable things!  How could I troubleshoot this? If it happens here it could happen elsewhere. 


speter

  • Sr. Member
  • ****
  • Posts: 345
Re: Very Weird SIGSEGV
« Reply #1 on: April 19, 2021, 08:27:32 am »
Without seeing more code, I don't think anyone can help you.
Is "setlabel()" a procedure you have written? Maybe it accesses a uninitialised variable/object.

Despite not being able to help much, I am definitely not suggesting that you shouldn't seek help when strange things happen. :)

cheers
S.
I climbed mighty mountains, and saw that they were actually tiny foothills. :)

dseligo

  • Hero Member
  • *****
  • Posts: 1196
Re: Very Weird SIGSEGV
« Reply #2 on: April 19, 2021, 08:36:40 am »
Try to change it like this (if gameplay.starting is integer):

Code: Pascal  [Select][+][-]
  1.   setlabel('TitleLine1', 'Team ' + IntToStr(gameplay.starting), 80, 1);
  2.   setlabel('TitleLine2', 'Choose a Category:', 80, 2);

Maybe there is a bug in the helper.

dbannon

  • Hero Member
  • *****
  • Posts: 2786
    • tomboy-ng, a rewrite of the classic Tomboy
Re: Very Weird SIGSEGV
« Reply #3 on: April 19, 2021, 09:40:10 am »
....
Run the program - no crash.  I didn't change anything in the lines.. all I did was just simply move them below another piece of code and it works! 

Some people will be saying "Why are you writing on the forum then if your code is working?" ... as I said I hate inexplicable things!  How could I troubleshoot this? If it happens here it could happen elsewhere.

rwebb, you are quite right to worry. It sounds to me like there is a memory problem somewhere, its possibly just chance where it pops up and tells the world. So, while you have hidden it for now, its still lurking in there, waiting for someone important to be watching ....

I would look for an uncreated object, an array you have not reserved enough space for and so on.  And try debugging, line by line through setlable() ....

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Very Weird SIGSEGV
« Reply #4 on: April 19, 2021, 03:27:43 pm »
Without seeing more code, I don't think anyone can help you.
Is "setlabel()" a procedure you have written? Maybe it accesses a uninitialised variable/object.

Yes I knew when I posted it was a bit lacking in supplied information - just not sure the best way to post it considering this is a rather large project (to me anyways) - lots of things happening up to this point and I'm guessing any one of those things could be involved.  Since I am learning the language (and the windows aspects of the language - event driven code etc) I'm sure that it could be something that I forgot to "free" or maybe didn't create etc. 

The purpose of this particular function is to provision a TLabel and place it at a predetermined position on the screen.  The arguments are:

  • Label Name - this corresponds to the name property on the label when created - also used for searching for existing labels in the object list
  • Value - this is the value that is applied to the caption property when the label is created
  • Fontsize - this is self-explanatory - sets the font size of the label
  • Location - this is the position on the screen where the label is supposed to be placed and centered

There is a labels object list that gets created at application startup and whenever a label is provisioned it's name is set according to the argument provided and then it is added to the objectlist.  Then when I try to "setlabel" and the name is the same as an existing one it will search for it in the objectlist and then return it if it exists or create a new one. 

So that is my first question - if a function returns an object as this does and I don't use the return value (don't do: var := setlabel()) is that a problem?  Setlabel is specific to this form and will place the label and "show" it

Quote
Despite not being able to help much, I am definitely not suggesting that you shouldn't seek help when strange things happen. :)
Yes, that is why I posted - thought it better to ask than leave it because I am sure I've not seen the last of it :)

Here is the code for the setlabel procedure:
Code: Pascal  [Select][+][-]
  1. Function TfGameboard.SetLabel(LabelName: String; Value: String;
  2.   FontSize: Integer; Location: Integer): TLabel;
  3. Var
  4.   index: Integer;
  5.   center: Integer;
  6.   labelcontrol: TLabel;
  7. Begin
  8.   center := self.Width Div 2;
  9.   labelcontrol := GetLabel(LabelName);
  10.   Result := labelcontrol;
  11.   With labelcontrol Do
  12.   Begin
  13.     Parent := self;
  14.     Caption := Value;
  15.     font.Size := FontSize;
  16.     Show;
  17.  
  18.     Case Location Of
  19.       1:
  20.       Begin         // Title line 1 location
  21.         Top := 80;
  22.         Left := center - Width Div 2;
  23.       End;
  24.       2:
  25.       Begin         // Title line 2 location
  26.         Top := 200;
  27.         Left := center - Width Div 2;
  28.       End;
  29.       3:
  30.       Begin         // Word location
  31.         Top := (self.Height Div 2) - Height Div 2;
  32.         Left := center - Width Div 2;
  33.       End;
  34.       4:
  35.       Begin         // Timer location
  36.         Top := (self.Height Div 2) - Height Div 2;
  37.         Left := center - Width Div 2;
  38.       End;
  39.       5:
  40.       Begin         // Word 1 Location
  41.         //Top := (self.height div 2) - height div 2;
  42.         top := 450;
  43.         Left := (center Div 2) - Width Div 2;
  44.       End;
  45.       6:
  46.       Begin         // Word 2 Location
  47.         //Top := (self.height div 2) - height div 2;
  48.         top := 450;
  49.         Left := center - Width Div 2;
  50.       End;
  51.       7:
  52.       Begin         // Word 3 Location
  53.         //Top := (self.height div 2) - height div 2;
  54.         top := 450;
  55.         Left := ((center Div 2) + center) - Width Div 2;
  56.       End;
  57.       8:
  58.       Begin         // Word 4 Location
  59.         //Top := (self.height div 2) - height div 2;
  60.         top := 650;
  61.         Left := (center Div 2) - Width Div 2;
  62.       End;
  63.       9:
  64.       Begin         // Word 5 Location
  65.         //Top := (self.height div 2) - height div 2;
  66.         top := 650;
  67.         Left := center - Width Div 2;
  68.       End;
  69.       10:
  70.       Begin         // Word 6 Location
  71.         //Top := (self.height div 2) - height div 2;
  72.         top := 650;
  73.         Left := ((center Div 2) + center) - Width Div 2;
  74.       End;
  75.       11:
  76.       Begin         // Word 7 Location
  77.         //Top := (self.height div 2) - height div 2;
  78.         top := 850;
  79.         Left := (center Div 2) - Width Div 2;
  80.       End;
  81.       12:
  82.       Begin         // Word 8 Location
  83.         //Top := (self.height div 2) - height div 2;
  84.         top := 850;
  85.         Left := center - Width Div 2;
  86.       End;
  87.       13:
  88.       Begin         // Word 9 Location
  89.         //Top := (self.height div 2) - height div 2;
  90.         top := 850;
  91.         Left := ((center Div 2) + center) - Width Div 2;
  92.       End;
  93.     End;
  94.   End;
  95. End;
  96.  

Also Pertinent is the GetLabel procedure:
Code: Pascal  [Select][+][-]
  1. function GetLabel(Name: String): TLabel;
  2. var
  3.   i,created:integer;
  4.   myLabel : TLabel;
  5. begin
  6.   Result := nil;
  7.   i:=0;
  8.   while i < labels.Count do begin
  9.     if (Tlabel(labels[i]).Name) = Name then begin
  10.       myLabel := Tlabel(labels[i]);
  11.       Result := myLabel;
  12.       exit;
  13.     end;
  14.     inc(i);
  15.   end;
  16.   // Existing label not found - create one and return the label
  17.   myLabel := TLabel.create(nil);
  18.   myLabel.Name:=Name;
  19.   myLabel.font.color := clWhite;
  20.   myLabel.font.name := 'Roboto Black';
  21.   created := labels.add(myLabel);
  22.   Result := TLabel(labels[created]);
  23. end;

I'm sure there are much better ways to do this but this is what I've come up with! :)

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Very Weird SIGSEGV
« Reply #5 on: April 19, 2021, 03:41:27 pm »
Try to change it like this (if gameplay.starting is integer):

Code: Pascal  [Select][+][-]
  1.   setlabel('TitleLine1', 'Team ' + IntToStr(gameplay.starting), 80, 1);
  2.   setlabel('TitleLine2', 'Choose a Category:', 80, 2);

Maybe there is a bug in the helper.

Tried that just now and still get the error - it errors on the second line - the first one executes ok. 
I've also tried changing the name and the value of the second line and it makes no difference as long as it's in this spot in the code. 

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Very Weird SIGSEGV
« Reply #6 on: April 19, 2021, 03:46:40 pm »

rwebb, you are quite right to worry. It sounds to me like there is a memory problem somewhere, its possibly just chance where it pops up and tells the world. So, while you have hidden it for now, its still lurking in there, waiting for someone important to be watching ....

I would look for an uncreated object, an array you have not reserved enough space for and so on.  And try debugging, line by line through setlable() ....

Problem is it won't even enter the procedure when I try to debug as soon as I hit F8 on the second line it gives me the error.

That is why I need help from all of you!  I need someone with more experience to help me learn how to debug this.  Maybe I'm foolish for attempting such a, well, "largish" project but at first glance when I started it seemed like a simple app to get my feet wet.  I'm finding it's much more involved than I first thought... although that is probably good - I like to be challenged and what better way to learn than to just jump in with both feet!

Rich
« Last Edit: April 19, 2021, 03:49:52 pm by rwebb616 »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Very Weird SIGSEGV
« Reply #7 on: April 19, 2021, 03:53:33 pm »
Obscure bugs are rarely found at third hand on the basis of code snippets posted on the forum.
Without sharing compilable sources I doubt that you'll get much more useful help.

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Very Weird SIGSEGV
« Reply #8 on: April 19, 2021, 04:11:10 pm »
Also if it helps here is a little background on this project.  I'm recreating a game that was originally designed to run on a phone called "Heads Up" .. I'm changing it in that I'm making it to run on a large screen TV and modifying it to be a teams based game.  My plan is to use it for our church youth group as a game to play. 

It runs on the Windows platform due to it's use of the Windows API to embed the fonts and use them in memory.  I am trying to keep it all able to run with a single executable with no client libraries required.  Just drop the EXE on a Windows machine and run it and it has everything it needs to run.  The backgrounds I'm using are used in the project resources and loaded to change "boards" and I plan to embed the wave files that I'll need for sounds as well.

Right now I'm trying to just get the game working and figured I'd add sounds later.  I am using a gameloop that runs on a timer and I'm using logic state booleans to move the game through it's various stages. 

I know that I'm lacking a lot of Try / Except / Finally statements as I never really know quite the best way to use them. Always looking for improvement though and better ways to do stuff.

A very experienced programming friend of mine once told me... "If you want to make your program run better just delete some code" and it's funny because I'm finding out that is quite a true statement.  When I go back through a procedure that I've written I'm going "well, that complete block is unnecessary ... DELETE".  Seems like the first revision is always inefficient.
Rich

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: Very Weird SIGSEGV
« Reply #9 on: April 19, 2021, 04:11:37 pm »
Problem is it won't even enter the procedure when I try to debug as soon as I hit F8 on the second line it gives me the error.

F7 is to enter.

F8 will step over, but not if something goes wrong inside. Though the debugger might stop, and show you where it went wrong. But not always.
To use the debugger, set debug type info to "dwarf with sets"

--
So use F7. Step in.
Before each step, have a close look at all the variables, parameters, locals... Maybe one of them is not what you expect.

Have you made sure the list, and all other objects involved are indeed created before the call? Yes I know, the firs call uses them too. But that does not mean anything. Could be luck.
If you deal with an uninitialized object, the code may crash, or may work. It may work once, but not twice....

Here is one thing to consider:
It is also possible that some code - even completely unrelated code - goes wrong, and due to uninitialized or range violation writes to memory it does not own. Then the error happens at some random place later. And moving code around may (or may not) hide the problem.

---
Have you set all the debug checks (range, object ...  checking)? -CRriot -gt  (also try -gtt or -gttt)
Turned optimization to zero -O-
Added Heaptrc -gh  (additionally search the forum for "keepreleased" option of Heaptrc)

If you are on Linux, instead of using Heaptrc, you can use valgrind.
Compile with -gv  and then start your app from console: valgrind --tool=memcheck yourapp
EDIT: posting overlapped / you are on Win



« Last Edit: April 19, 2021, 04:17:32 pm by Martin_fr »

ccrause

  • Hero Member
  • *****
  • Posts: 845
Re: Very Weird SIGSEGV
« Reply #10 on: April 19, 2021, 04:28:25 pm »
I was going to suggest proper debugging options, but Martin just beat me to it.  If you experience funny stepping during debugging, check that optimization is not set to higher than 1.

My guess is that something is messing up the stack. Are you perhaps manipulating strings or dynamic arrays in a "clever" way?

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Very Weird SIGSEGV
« Reply #11 on: April 19, 2021, 04:32:36 pm »
Quote
F7 is to enter.

Well this helped a LOT... It seems I knew this but got so used to using F8 I didn't think of it.  Ok so now it's going into the GetLabel procedure and it goes through the while loop the first time for item 0 and then it chokes on item1.  I modified the loop as follows so I could see variable values because for some reason I can't get the value from labels.count but I can from a variable... same with Tlabel(labels).name:

Code: Pascal  [Select][+][-]
  1.   lcount := labels.Count;
  2.   while i < lcount do begin
  3.     lName := Tlabel(labels[i]).name;
  4.     if (Tlabel(labels[i]).Name) = Name then begin
  5.       myLabel := Tlabel(labels[i]);
  6.       Result := myLabel;
  7.       exit;
  8.     end;
  9.     inc(i);
  10.   end;

And when it hits LName where it is assigned the name of the TLabel it crashes.  So apparently I must not have set the name on one somewhere (not sure how given that the function does that) ... probably need to track all labels created start to this point and make sure they're being created properly now...

Quote
Have you set all the debug checks (range, object ...  checking)? -CRriot -gt  (also try -gtt or -gttt)
Turned optimization to zero -O-
Added Heaptrc -gh  (additionally search the forum for "keepreleased" option of Heaptrc)

No idea what all of those do - probably need to learn about that as well.  I'm not quite that advanced yet :)

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Very Weird SIGSEGV
« Reply #12 on: April 19, 2021, 04:34:40 pm »
Are you perhaps manipulating strings or dynamic arrays in a "clever" way?

Not that I know of - at least not intentionally... I don't have any dynamic arrays at the moment .. I used to and then I moved to using a TFPObjectList instead. 

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Very Weird SIGSEGV
« Reply #13 on: April 19, 2021, 04:41:16 pm »
Could it be this simple? 

Code: Pascal  [Select][+][-]
  1.  lcount := labels.Count;
  2.   while i < lcount do begin
  3.     lName := Tlabel(labels[i]).name;
  4.     if (Tlabel(labels[i]).Name) = Name then begin
  5.       myLabel := Tlabel(labels[i]);
  6.       Result := myLabel;
  7.       exit;
  8.     end;
  9.     inc(i);
  10.   end;                                      

labels.count is one based and the index for labels is zero based...

So shouldn't it be:
Code: Pascal  [Select][+][-]
  1. while i < lcount -1 do begin

This has bitten me before as well! :)

Rich

rwebb616

  • Full Member
  • ***
  • Posts: 133
Re: Very Weird SIGSEGV
« Reply #14 on: April 19, 2021, 06:00:54 pm »
Ok found the culprit.  Well it was a combination of things.  First was what I mentioned.. the zero based vs 1 based issue.  I also discovered that the while loop wasn't working as I expected it would so re-wrote it as a for loop:

Code: Pascal  [Select][+][-]
  1. for i:=0 to labels.count -1 do begin

Then I got another SIGSEGV but it got further.. tracked it down and realized that one of the labels in the labels object list was missing so I had obviously freed it at some point.  Tracked it down and sure enough I had freed one of the labels.  This was before I learned how the variables are pointers to the object in the list - I was thinking I was freeing the local object when I was actually freeing the one in the objectlist.  Commented that out and it was working again - no errors...

The primary help in this case was the suggestion of the F7 key which I knew about but had forgotten.  So THANK YOU for everyone who chimed in.  I'm sure I will eventually have more. 

Once I get this thing working maybe I'll post the code if people want to use it or do whatever with it.
Rich

 

TinyPortal © 2005-2018