PDA

View Full Version : Flexsim Debugger


Anthony Johnson
01-11-2009, 01:49 AM
Hey Flexsim Users,
For our next major release we are considering implementing a Flexsim debugger to help you in weeding out bugs, exceptions, modeling errors, etc. To some extent, however, we are at a loss as to what exactly that debugger should contain. Up to this point, each Flexsim user has learned his own set of tips and tricks in finding and resolving modeling issues, so I'm sure the debugging methods vary widely.

Subsequently, we would like to get your input as to what you think should be included in a good debugger. Please consider, in making your suggestions, previous modeling problems that you have encountered, how you found and fixed them, and what type of tool would have helped you in that process.

Also, for those users who have used other simulation packages, could you described how that package's debugger worked, as well as what you liked and disliked about it?

Thanks,

AJ Bobo
01-12-2009, 11:16 AM
While I haven't used debuggers in other simulation packages, I've used Visual Studio's debugger a lot. Here are the features from it that I use the most. (These are probably the sort of features that Anthony already has in mind, but I'm throwing them out to start the discussion more than anything.)

1) Variable watches - The debugger will show me the current values for a set of variables that I want to know about. This often removes the need to write code (that I will just remove later) to print the values of certain variables.
2) Line-by-line execution - Each line of the function executes only when I tell the debugger to advance. This way I can check the values of my variables (see item 1) before a line executes and then again after it.
3) Step-into/over - If, while step-by-step debugging, I come to a function that I wrote, I have the option of "diving" into its code to step through it or I can simply let it execute and move on to the next line in my current function. This can save a lot of time, but also gives you the option of seeing what's happening in a program in more detail.
4) Break-points - I select lines of code where the execution will automatically stop if I am debugging. If I know that a bug is occurring in a particular function, I will put a break-point at the beginning of the function and let the program run normally until that function is called. Then I step through just that function.
4a) Conditional break-points - (I haven't used this as much as the other features on the list, but it can be handy) I can assign a small function to each break-point that is executed by the debugger whenever the break-points are encountered. If the function returns true, the program execution stops. If the function returns false, the program continues running normally.
5) View call stack - The debugger shows the function that called the function I am currently debugging, and the function that called it and so on back. This can be very handy if you have a function that is called from a lot of different places in your program.

Steven Hamoen
01-12-2009, 02:08 PM
I think that AJ's remarks are very usefull.

Considering the Conditional break-points, those can be very handy if the error appears after a certain amount of time or a number of product handled. You can run to that point and then start debugging.

What I know from a different product from the past:D is the function count and the % of the execution time that a certain function is responsible for. Those can be very usefull if you want to improve or speed up your model.

Steven

Kris Geisberger
01-14-2009, 03:45 PM
I like all of the suggestions so far!

I don’t have much experience with debuggers, but I figure a good tool would help me see exactly what is being executed, in sequence (hopefully in more words I understand) so that I could identify when it is not what I expected. I thought about this a bit and I tried to work from the problems toward the desired functionality.

Problems:
If there are no syntax errors and the model visuals don’t help me debug further, usually I have:


code in the wrong place

code not executed when expected
code executed when expected, but then overruled by standard object behaviour functions


mistakes in the code itself

not the right commands – not doing what I expected
right commands with wrong inputs
bad calculations or object pointers



To expand, I think a lot of model 'bugs' are a result of the user:


lacking order of execution knowledge

expecting that a label set OnExit will be considered by a downstream object's PullRequirement


misunderstanding WHEN their custom code is executed relative to standard Flexsim object behaviour functions

ex. TE chose a new tasksequence to work on before the user dispatched their own custom tasksequence… that they wanted the TE to chose instead


lacking knowledge of what a particular object behaviour function manages, especially when it overrides what they did in a trigger

setting item location
managing a variable value
opening or closing ports
setting object state


making a numerical mistake that is passed into a command

wrong table cell lookup
negative delay time on message created
msgparams


making a bad object pointer that is passed into a command

setloc
sendmessage
setlabel or setitemtype


creating an infinite loop

for loops
while loops
code in SendToPort, PullRequirement, OnMessage - releaseitem(), openoutput()


mixing sendmessage vs. senddelayedmessage in 0 time


Functionality:
During step debugging, present the following information


Current object name
Current function name (trigger, evaluation, etc.)
Current function code
List of all variables passed into the current function

Ex. for OnMessage, if a msgparam is an object pointer show its name and highlight the object/item (or center in view) when the user double clicks on the msgparam in the list


Current line of code debugger is on
Local variables added to a temporary list as they are created and their values updated (until the function is complete – then the list is cleared). I guess this would include most variables passed into the function, except msgparm() and msgsendingobject. If the function is long with a lot of variables you can add a select few to a watch list, along with any Global Variables you want to watch.
The actual values or object names passed into a command (not variables or more commands)
Returned values of commands, especially the "get...()" commands
Ex. Process Time evaluation

CODE VIEW:
Line1 | treenode current = ownerobject(c);
Line2 | treenode item = parnode(1);
Line3 | treenode port = parval(2);/**By Global Table Lookup*/
Line4 | /** \nTable: */
Line5 | string tablename = /**/"Table1"/**/;
Line6 | /** \nRow: */
Line7 | int row = /**/getitemtype(item)/**/;
Line8 | /** \nColumn: */
Line9 | int col = /**/getlabelnum(current,1)/**/;
Line10|
Line11| return gettablenum(tablename,row,col);
DEBUGGER VIEW:

Line7: getitemtype() on object “Textured Colored Box”, returned 14
Line7: declare integer named row = 14
<Step>
Line9: getlabelnum() on object “Combiner12”, rank 1 (named ”nextcolumn”), returned 2
Line9: declare integer named col = 2
<Step>
Line11: gettablenum() on table "Table1", row 14, column 2, returned 35.1
Line11: Process Time return = 35.1

9. Dynamic error report, similar to the system console integrated into the debugging interface.


NULL object pointer, node (label or table) does not exist
global table does not exist
negative delay time in senddelayedmessage()
negative return value in a process/setup time evaluation


10. Dynamic view of the event queue (profileevents), to give awareness of where/when future events are created and what event is next

11. Some trace of what has been executed, and where it is located (call stack?) DEBUGGER TRACE:
LIBRARY:/Combiner>behaviour/cppfunctions/OnReceive - Start
MODEL:/Combiner12>variables/entrytrigger
*STEP DEBUG*
LIBRARY:/Processor>behaviour/cppfunctions/startsetuptime - Start
MODEL:/Combiner12>variables/setuptime
*STEP DEBUG*
LIBRARY:/Processor>behaviour/cppfunctions/startsetuptime - End
LIBRARY:/Combiner>behaviour/cppfunctions/OnReceive – End
12. Brief comments on object behaviour that is executed Ex. Combiner - OnReceive behaviour executed
sets location of item within combiner
closeallip of combiner
executes entry trigger
*OnEntry debug*
sets the state of the combiner
manages componentlist variable table
*SetupTime debug*
13. …all in one interface I can move to monitor 2 while I have my model view on monitor 1. :rolleyes:

Alex Christensen
01-15-2009, 11:39 AM
The kinds of bugs that bug me are the ones that cause Flexsim to crash and I usually lose some of my work. I'm not sure if it's possible to implement this, but I think it would be useful to have a Control-C or a break button that would break out of all flexscript execution so you don't have to restart if you get into an infinite loop.

Also, I would like a check on infinite recursion in Flexscript. Right now if you make a command called command1 with this code:

int x=parval(1);
msg("",numtostring(x));
command1(x+1);

On my computer, calling command1(0) gets to 170 then crashes Flexsim. The same problem exists when you have a node call nodefunction on itself.

Jason Lightfoot
01-20-2009, 07:22 AM
Great suggestions everyone.

I'd like to add summary statistics for code we write.

1. Number of times the code (per node) was called
a. With a breakdown showing from where it was called (with counts)

2. The amount of time spent executing the node's code.

I think this would assist debugging AND help us to focus on bottleneck chunks of code (either due to speed or number of times executed)

These execution stats would need to be toggleable I guess to cut out any overhead.

Carsten Seehafer
02-06-2009, 05:37 AM
I would love it if you could earmark an objekt. Everytime a peace of code interacts with this object, it'll show the line of code and step forward line by line.

With this functionality you could find out why an object isn't working as expected.