SE 12.0.3 r35, on Vista Ultimate:
While using the Regex Evaluator, I locked up SE at 100% CPU (I had a regex that appeared to match the whole line but I thought should match two separate substrings in the line, and it occurred to me that depending on how the regex is evaulated it could match three times that overlapped each other, so I appended \c to the regex to see if that would help, but SE went to 100% CPU and Ctrl+Shift+Alt+F2 could not break in). I killed SE.
When I restarted SE, it went to 100% CPU again. Ctrl+Shift+Alt+F2 gave me a stack:
c.ex 4337 _clex_skip_blanks(m) p_window_id: 5 p_object: OI_FORM p_name:
smartp.ex 2066 c_smartpaste(0,1,733) p_window_id: 5 p_object: OI_FORM p_name:
smartp.ex 1305 e_smartpaste(0,1,733) p_window_id: 5 p_object: OI_FORM p_name:
smartp.ex 4819 static(3488,C,,,1,e,1) p_window_id: 5 p_object: OI_FORM p_name:
smartp.ex 4573 static(3488,24,C,,,1,e,1) p_window_id: 5 p_object: OI_FORM p_name:
smartp.ex 566 static(24,C,,1) p_window_id: 5 p_object: OI_FORM p_name:
smartp.ex 118 smart_paste(24,C,,1,) p_window_id: 15 p_object: OI_FORM p_name:
stdcmds.ex 15497 _copy_or_move(24,C) p_window_id: 15 p_object: OI_FORM p_name:
stdcmds.ex 15335 copy_to_cursor(24) p_window_id: 15 p_object: OI_FORM p_name:
put.ex 447 get(c:\slick\config\autosave\FindIn.e,,A,0,0,) p_window_id: 15 p_object: OI_FORM p_name:
autosave.ex 2155 static() p_window_id: 15 p_object: OI_FORM p_name:
Slick-C STACK TRACE ******************************
Created on 3/24/2008 at 20:19:29 (335 ms)
After some poking around and using another instance of vs.exe to edit and recompile autosave.e with debug trace output, I found that it is trying to recover an autosaved file, but it gets into an infinite loop inside
_autosave_check:
static void _autosave_check()
{
if ((def_as_flags & AS_SAMEFN)) return;
// For each of the buffers, check for an autosave file.
int orig_view_id;
get_window_id(orig_view_id);
messageNwait('BEFORE-BEFORE: orig_view_id='orig_view_id', p_buf_id='p_buf_id);
activate_window(VSWID_HIDDEN);
_safe_hidden_window();
//activate_window orig_view_id
int orig_buf_id = p_buf_id;
messageNwait('BEFORE: p_buf_id='p_buf_id', p_buf_name="'p_buf_name'" ... '_time());
int count=0;
for (;;) {
_str filename=_mkautosave_filename();
if (filename!='') {
typeless bfiledate=_file_date(filename,'B');
if (bfiledate!='' && p_file_date<bfiledate) {
typeless p=p_line;save_pos(p);
_lbclear();
get(maybe_quote_filename(filename),'','A');
//p_modify=1; get() will set ModifyFlags to 1
++count;
//message_up=1;messageNwait('p_buf_name='p_buf_name'p='p);message_up=0;
restore_pos(p);
}
}
_next_buffer('hr');
messageNwait('NEXT: next buffer='p_buf_id' ... '_time());
if (p_buf_id == orig_buf_id) {
break;
}
}
p_window_id=orig_view_id;
if (count) {
refresh();
message_up=1;
_message_box("AutoSave has detected an abnormal exit. The window/buffer configuration has been restored. Modified files have been restored to last AutoSave.");
message_up=0;
}
}
The
BEFORE-BEFORE: message shows
orig_view_id=15, p_buf_id=9.
The
BEFORE: message shows
p_buf_id=0, p_buf_name=".command".
The
NEXT: message cycles through
p_buf_id=7, 8, 9, 7, 8, 9, 7, 8, 9, ... and never gets back to 0, so it never breaks out of the loop.
I could detect the cycle using any of the typical cycle detection algorithms (e.g. a hash table, tortoise and hare, countdown, etc), but p_buf_id starts as 9 which gets hit repeatedly during the cycle, so I'm certain there is a better fix that avoids the cycle altogether. Can a Slick team member suggest an elegant fix? For the moment I've used a workaround to put the visited buffer ids in a hash table and break when it finds a collision, because that's a quick'n'simple surefire workaround. But it's not a very nice solution.
As an aside: The hash table successfully broke out of the loop, and then I discovered that the autosave file was unexpectedly empty (only contained a single blank line, and confirmed that the autosave disk file was only two bytes).