Sign in to follow this  
Followers 0
KJohn

Better crashes

17 posts in this topic

This is the context: Large programs (2000+ lines) distributed as compiled scripts which despite extensive testing may crash on maybe one/few of 100s/1000s of users' machines for reasons unique to the end users' environment(s). End users may be willing to only give the error displayed when the script crashed.

What would help: Autoit including the option to dump the text of the line being parsed when it crashed to say a text file set as an option in the beginning. Maybe even with basic encryption of that line of code (password set as an option). The user can then just pass it on to the compiled script's author for analysis. This would really help with debugging when the crash cannot be replicated on the author's machine or the end user is unable to describe the conditions required to replicate the crash.

I can understand the irrelevance of displaying line number from a compiled script (because of includes, comment stripping, etc.) but maybe this would be more useful?

Share this post


Link to post
Share on other sites



No. I am not willing to make you the guarantee that we will maintain such a feature. One of my dream goals is to see an "optimizing compiler" for AutoIt which converts scripts into a form of optimized byte-code. I'm not saying such a feature would come anytime soon, I'm just saying I want to leave the door open for that sort of thing. Making guarantees about what sort of information we will provide on error is counter to that.

Further, there's no reason a script should crash. If it's an AutoIt hard-crash then that's something we should fix. If it's a script error crashing then that's something you can fix with defensive programming. Assuming the script passes Au3Check, checks all array bounds before indexing and has a COM error handler (if using COM) there's not much reason a script will fail. Which means it's up to you to trap those errors and log them as appropriate.

So really, there's not much need of a feature like this.

Share this post


Link to post
Share on other sites

No. I am not willing to make you the guarantee that we will maintain such a feature. One of my dream goals is to see an "optimizing compiler" for AutoIt which converts scripts into a form of optimized byte-code. I'm not saying such a feature would come anytime soon, I'm just saying I want to leave the door open for that sort of thing. Making guarantees about what sort of information we will provide on error is counter to that.

Further, there's no reason a script should crash. If it's an AutoIt hard-crash then that's something we should fix. If it's a script error crashing then that's something you can fix with defensive programming. Assuming the script passes Au3Check, checks all array bounds before indexing and has a COM error handler (if using COM) there's not much reason a script will fail. Which means it's up to you to trap those errors and log them as appropriate.

So really, there's not much need of a feature like this.

I didn't think of it that way. I understand and support your reasoning but let me present a real scenario that I faced where the information provided by AutoIt was a little too little.

I have a program called neoSearch that used to crash for about 1 in every 8000 users. It's a desktop search program and during indexing, in order to correlate the file-type of a file to more information (in an array) regarding files of that type, I used to use the Eval($extension) statement to obtain an index value. I found this much much faster than manually looping and matching to elements in the array. I know this is not a programmatically sound practice but it helped optimize file-indexing speed when 2000 odd files are being processed per second.

The program used to crash when it encountered by a rare chance a file with an extension that matched one of the hundred or so "actual" variables I used in the program. Eval used to return an index value that would almost invariably be out-of-bounds. This was a situation that's very hard to replicate. The users would "disappear" after reporting the problem so following up with a specially compiled version (with a lot of unnecessary defensive programming code; and terribly speed challenged) was useless.

It's easy point to this and say I screwed up my programming but with the myriad of possibilities I was faced with, I was at a loss to figure out where to start debugging. It was 6 months after the first reported incident (there were about 3), that the possibility struck me and I fixed it.

You stated that you didn't want to guarantee what sort of information you will provide on a crash. I agree that is the most responsible position to take considering your goals. But I sincerely feel that any sort of additional information that AutoIt could provide, in the manner I proposed, would be a huge help. Something similar to a dump file, where the contents are not guaranteed but nonetheless helpful. For example, information can include how long the script ran before it crashed.

In short, you don't have to guarantee the nature of the information and yet, it would be a proactive step forward. If the answer is still no, I will leave it at that - I just wanted to present why I felt it would be helpful.

Share this post


Link to post
Share on other sites

I'm going to be intentionally ambiguous here. I've thought about a "compiler" quite a bit and the simple matter is, I can't promise anything useful ever being providable if such a compiler ever exists. Running time could certainly be provided but that's about it. It's an awful lot of infrastructure just for one tiny bit of information.

Besides, you can solve the issue yourself with clever design. Have the script's normal startup be a simple routine that logs when it starts and has some code in it to monitor for failure. The script then re-runs itself passing a special flag which triggers the real code. Yes, there would be two processes running with this. The first process could monitor for error windows and write log data. The second (real) process could use STDIO to pipe data back to the parent process which would be logged on a crash. For example, each important function you call could do a quick ConsoleWrite() to send the data to the parent process. If the parent detects the child crashes then it could write the data to the file. If the child doesn't crash then the data is discarded.

Share this post


Link to post
Share on other sites

I'm going to be intentionally ambiguous here. I've thought about a "compiler" quite a bit and the simple matter is, I can't promise anything useful ever being providable if such a compiler ever exists. Running time could certainly be provided but that's about it. It's an awful lot of infrastructure just for one tiny bit of information.

I understand. At least I think I do.

Besides, you can solve the issue yourself with clever design. Have the script's normal startup be a simple routine that logs when it starts and has some code in it to monitor for failure. The script then re-runs itself passing a special flag which triggers the real code. Yes, there would be two processes running with this. The first process could monitor for error windows and write log data. The second (real) process could use STDIO to pipe data back to the parent process which would be logged on a crash. For example, each important function you call could do a quick ConsoleWrite() to send the data to the parent process. If the parent detects the child crashes then it could write the data to the file. If the child doesn't crash then the data is discarded.

I am already aware of this solution but I won't be implementing it because knowledgeable users want to know what every process on their system is doing and they don't like unnecessary processes. I don't think I have anything more of value to contribute to this discussion within the limits of my knowledge but thank you very much for taking the time to reply. It would be nice if the developers could toss this among themselves in private sometime because this feels like an area warranting improvement.

Share this post


Link to post
Share on other sites

I could be off base here but it runs in my mind that Jon explained to me at one time that vertical white space is stripped at compile time so everything appears to be on a single line. That's why the Error reported is always indicated on the same line (line 0 as I recall) and there is really no way to reference that to the actual line in your script. However at that time comments were also stripped and I'm sure that is not the case any longer so it's possible that this doesn't apply either.


George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

George, that's not really it. Included files are inserted inline so what appears to be line #2 might really be line #2983 depending on the size of the files included before it. Also, it's true that at one time the compiler did strip comments. I can't recall if it does now or not. I don't think that it does, actually.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

George, that's not really it. Included files are inserted inline so what appears to be line #2 might really be line #2983 depending on the size of the files included before it. Also, it's true that at one time the compiler did strip comments. I can't recall if it does now or not. I don't think that it does, actually.

I'm certain that comments are no longer strpped. I just don't recall all of Jons explanation now and it was a long time ago that I raised a question about it. And of course few people really know much about the compiler. Edited by GEOSoft

George

Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.

Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.***

The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number.

Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else.

"Old age and treachery will always overcome youth and skill!"

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Comments were stripped when an official decompiler existed. People (as usual) bitched about this so it was changed so that comments were no longer stripped so people decompiling could get them back. I don't believe we've ever went back to stripping comments since we stopped distributing a decompiler.

Edited by Valik
Typo corrected

Share this post


Link to post
Share on other sites

Pity it's not an option at compile time (comment stripping I mean). I'd certainly like to be able to strip the comments out of any *.exe I distribute.

Share this post


Link to post
Share on other sites

Hello to all,

Upon reading your dilemma I thought that I should give you a solution I used to use 20 odd years ago. :P

I forget what the language was (MUMPS or Clipper perhaps), anyway, what is important is that the method I used was simple and straightforward involving no extraneous functions or services.

Assign a 2 letter code (AA, AB, AC...) to each script/program

Assign a 2 letter code (AA, AB, AC...) to each function/procedure.

Assign a 3 digit code to key points/lines of script that you wish monitored within your code.

Using these codes, write them out to a log file at key points/time in your script, when the script finishes normally have your script delete the log file. then when/if the script crashes the log file will NOT be deleted and upon restart a quick check for its existance will show that there was a crash, have a message pop up to the user explaining that there was a program crash detected and ask them to provide any relevant information in a text box explaining what may be the cause of the crash in their opinion.

For example it may simply have been only a power outage, or they may have something concrete to add in the way of explaination.

Either way have your script then rename the log file and create new one to start over.

The renamed log file may either be automatically emailed to you or notification of the crash instead, for you to then take further action against.

e.g.

Say one of your apps is called search.au3 then you might code it as AA.

Then if you have 10 different functions within the app they could also be referenced as AA, AB, AC... AJ

And finally assuming that you have several key points within your app where an algorithm needs to be monitored to see if has started and completed successfully then use the 3 digit code for each one.

Have these codes written to the log file concatenated with the apps current run date/time, (e.g AADF003-0903150955 = App AA, Fn DF, Keypoint 003, Date & Time) they will not be very long and therefore take up very little space plus they will mean nothing to anyone who reads the log file as the codes will only be relevant to the actual source code of yours.

In pseudo code:

CODE
Start of your app

check for existance of log file

if log file exists then rename it and inform user, get their infos, save it and inform you.

Start new log file.

Blah blah blah (lines of code you dont wish to monitor)

Blah blah blah (lines of code you dont wish to monitor)

Blah blah blah (lines of code you dont wish to monitor)

;Following line has critical code you want to monitor.

Write AA000datetime to log file (Start monitoring of code object 000)

Perform your critical code

Write AA000datetime to log file (Ends monitoring of code object 000)

;If you have crash whilst running object 000 then there will not be an End monitor for that object.

Blah blah blah (lines of code you dont wish to monitor)

Blah blah blah (lines of code you dont wish to monitor)

;To monitor a Fn call

Call Fn = Func_Refresh_Index

Blah blah blah (lines of code you dont wish to monitor)

Tidy up of processing and quit application, delete log file, no longer needed app finished successfully.

;Now say we have one of your many functions here.

Func_Refresh_Index

;assign 2 letter code to the Fn, say AA

Write AAAAdatetime to log file (Start monitor of Fn AA) ;You now have info stating The App, The Function start date and time

Perform your Fn code

;Say there is a critical line you want to monitor within the Fn

;Then assign it a different 3 digit No.

Write AAAA123datetime to log file (Start monitor of code object 123) ;You now have info stating The App, The Function, The object within the Fn and its start date and time.

Line of important code...

Write AAAA123datetime to log file (End monitor of code object 123) ;You now have info stating The App, The Function, The object within the Fn and its end date and time.

Blah blah blah (lines of code you dont wish to monitor)

Write AAAAdatetime to log file (End monitor of Fn AA) ;You now have info stating The App, The Function end date and time

I hope that I have explained it sufficently and that it is of use to you.

BTW: I would like to thank everyone on the forums for being so generous and giving with their talents and time, it is a great forum and supports a great scripting language AutoIt. :unsure:

Good Luck.


Quote of the week:"BASIC programmers never die, they GOSUB and don't RETURN." -- UnknownWisdom of the ages:

  

  • I'd be unstoppable... if not for law enforcement and physics.
  • Marriage, the number 1 cause of divorce.
  • Don't steal... the government hates competition.
  • Irish Government Motto: We’ve got what it takes to take what you’ve got.
  • Birthdays are good for you. Statistics show that the people who have the most live the longest.
  • Failure is not an option. It comes bundled with your Microsoft product.-- Ferenc Mantfeld
  • If you learn from your mistakes, then why ain't I a genius?! -- Anonymous
  • Remember, live every day as if it was your last day! one day you will be right.
  • How is it one careless match can start a forest fire, but it takes a whole box to start a campfire?
  • Sure my system is secure, it just locked up again.
  • I haven't lost my mind; I have a tape back-up somewhere.  ~Author Unknown

Share this post


Link to post
Share on other sites

@GerrOrneg

There is a performance penalty involved with this. FileWriteLine, for example, when used without a file handle will take longer and longer for each filewrite as the logfile grows. If you do use a file handle, and the script crashes, not all the filewrites will have been committed to the log file unless you have used FileClose on the handle. I remember reading somewhere that Valik implemented a FileFlush function in a beta version of AutoIt but I am inclined to think there is also a performance penalty to this.

I used to use log files in my programs but they proved pointless because it was a feature bloat in terms of performance and junk on the user's machine when everything was fine but in case of any failure, (in my type of programs) the cause would be difficult to identify with just a simple log. Sometimes a line by line logging would be required and it is just a waste of time to implement that in 2000 line programs. Which brings us back to why this thread was started. It is a problem with no easy solution.

Share this post


Link to post
Share on other sites

@GerrOrneg

There is a performance penalty involved with this...

True, there would be, but how about having a 'special' version of your app with the embedded monitoring codes implemented, that you then bundle along with your 'real' app in the installer?

Given that AutoIt compiles to a small executable it would not be a problem, you could then just ask your customers to run the 'special' debug version in cases where there was a lot of crashes, explaining the speed loss to them as a diagnostic, at least this would help you pinpoint where the problems are occurring. [Even this could be automated, if your app detects the log file, then let it quit but not before running the 'special' ver with appropriate message to the user.]

Then you may be able to solve it for all time, fix it, then redistribute the fix, viola, no more need to have users run the 'special' ver.

One other option has just occurred to me, using the embedded monitoring codes, but NOT having the app write them to a log file, have a second app running that does nothing but cache these codes sent to it from your app by say some form of inter-app memory swap, it then could log these as chunks of or complete log files (depending on their size) even if the main app crashed, hopefully the passing of the data through memory would not be such a speed black hole.

Either way, I wish you luck with finding a solution. :P


Quote of the week:"BASIC programmers never die, they GOSUB and don't RETURN." -- UnknownWisdom of the ages:

  

  • I'd be unstoppable... if not for law enforcement and physics.
  • Marriage, the number 1 cause of divorce.
  • Don't steal... the government hates competition.
  • Irish Government Motto: We’ve got what it takes to take what you’ve got.
  • Birthdays are good for you. Statistics show that the people who have the most live the longest.
  • Failure is not an option. It comes bundled with your Microsoft product.-- Ferenc Mantfeld
  • If you learn from your mistakes, then why ain't I a genius?! -- Anonymous
  • Remember, live every day as if it was your last day! one day you will be right.
  • How is it one careless match can start a forest fire, but it takes a whole box to start a campfire?
  • Sure my system is secure, it just locked up again.
  • I haven't lost my mind; I have a tape back-up somewhere.  ~Author Unknown

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

everything was fine but in case of any failure, (in my type of programs) the cause would be difficult to identify with just a simple log. Sometimes a line by line logging would be required and it is just a waste of time to implement that in 2000 line programs. Which brings us back to why this thread was started. It is a problem with no easy solution.

in the early days of AutoIT 3, when the source code was still public (~ 2005), I implemented some macros for that purpose (@ScriptLineNumberBefore, etc.), but Jon opted against it, due to the runtime overhead of those macros. Since then I do this:

I write debug code all over the script, which will not be executed during normal script operation. The debug flag and a debug level will be triggered by a command line switch, which means the user, who finds a problem, will have to re-run the script with debug option. In debug mode I do log every func entry and exit, I do log variable names and content and the like. With this strategy, I was able to find every bug so far. However, I was "lucky" and there were not really much bugs yet ;-))

If the debug switch is not an option for your users, there is little you can do to trap those cases you describe, EXCEPT to make your program more fool proof by adding as much error checks as possible and to avoid situations where AutoIT could fail internally (e.g. EVAL), which never happened in any one of my scripts so far, and I do use AutoIT for scripts with ~ 10.000 lines of code (not just dumb if clauses, but well structured code ;-)).

There is however something you could do to automate the debug process. Valik mentioned this already. I suggest a slight modification. Run one master script, which uses RunWait() to run the "worker" script. The master script will check the return status of the worker and if it detects any abnormal exit, it will restart the worker with the same options AND the debug flag. That could be a way to automate the process. Obviously this will not work in all cases, as the environment might have changed during the second run, but it is better than nothing :-))

I could imagine some kind of ring-buffer for log events, built into AutoIT, which will be written to disk when a script "crashes". However this will only work for those cases where AutoIT detects a problem and terminates the script and not real crashes.

EDIT: BTW. If speed is your biggest concern against debug code, AutoIT might be the wrong language/environment for your task.

Cheers

Kurt

Edited by /dev/null

__________________________________________________________(l)user: Hey admin slave, how can I recover my deleted files?admin: No problem, there is a nice tool. It's called rm, like recovery method. Make sure to call it with the "recover fast" option like this: rm -rf *

Share this post


Link to post
Share on other sites

Pity it's not an option at compile time (comment stripping I mean). I'd certainly like to be able to strip the comments out of any *.exe I distribute.

If it's an option we should just turn it back on if it's not already. No real need for it to be a user-facing option since once a script is compiled you should treat it as being unrecoverable.

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

I like /dev/null's idea about having a commandline switch to turn on debug/logging features.

Also, better for the compiler to strip the comments and names, hmm ? :P

(It's also a matter of executable size)

Edited by Inverted

Share this post


Link to post
Share on other sites

I think scripts are actually pre-lexed now when they are compiled so that's even better than stripping comments and excessive whitespace.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0