Subject: [Vim-vms] FW: 1 bug pin-pointed, 1 new bug (fwd)

From: [email-masked]
Date: Fri, 3 May 2002 10:20:09 +0200

---------- Forwarded message ----------
Date: Thu, 2 May 2002 13:38:18 +0200
From: Coen Engelbarts <[email-masked]>
Reply-To: [email-masked]
To: "Vim-Vms mailing list (E-mail)" <[email-masked]>
Subject: 1 bug pin-pointed, 1 new bug

Hi all,

Vim on VMS has a nasty bug that causes vim to crash sometimes.
It has annoyed me a lot. Vim is NOT supposed to crash!
I tried to find the bug and I think I found some good clues, and a new bug.
Please comment. Sorry if it's a bit long.

The crash seems to occur whenever you change file/syntax. Even :help
<something>, when vim has no files open, sometimes crashes.
I've only seen it with GVIM, but that may be because I have syntax=off on
terminal vim.

Today's way to reliably reproduce the crash:
	In the directory with Vim's sources, do:
	$ gv main.c
	:tag char_u
At the DCL prompt you'll see:
	TIGER2:CENGELBARTS:M45> Vim: Caught deadly signal BUS
	Vim: Finished.

I want a stack trace.
On Unix, a crashing program produces a "core" dump-file, which can be read
with a debugger, to produce a stack trace and values of variables at the
time of the crash. On VMS, there is no core dump, but you can compile with
/DEBUG and run the program with the debugger.
Unfortunately, my debug-Vim blatantly refuses to crash. :-(

However, there's another way to get a stack trace on VMS.
When a VMS program crashes, the standard VMS exception(signal) handler
prints a stack trace. (I hope I understand VMS correctly here.)
Vim-on-VMS does not do that, because any deadly signal/exception is handled
by the function deathtrap() (on VMS in os_unix.c), so vim can attempt to
save the swap file and session info before exiting. Thus, no standard VMS
exception handler, and no stack dump.

I think this is a bug (unless I misunderstand VMS here), or at least a
missing feature.  ;-).
When Vim on VMS receives a deathly signal, it should print a stack trace to
SYS$ERROR.
I don't know how to do this exactly.
Perhaps there is a way to print a stack trace in deathtrap().
Perhaps there is a way to call the standard VMS exception handler after the
Vim exception handler has finished.
It's complicated because Vim installs Unix-like signal handlers, ported to
VMS, not VMS-like exception handlers.
Anyway, I think this should be high on the to-do list for Vim on VMS.

For the moment, I devised a cunning plan: I just went and removed all
vim-code that installs signal handlers.
In main.c, I removed the call to atexit(vim_mem_profile_dump);
In os_unix.c, I removed all code in set_signals() and mch_early_init().
And Lo and Behold, it worked!

TIGER2:CENGELBARTS:M45> gv main.c
%DCL-S-SPAWNED, process CENGELBARTS_1 spawned
TIGER2:CENGELBARTS:M45>
%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual
address=000000005245535D, PC=0000000000093660, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
  image    module    routine             line      rel PC           abs PC
 VIM  BUFFER  find_wininfo              72984 0000000000003660
0000000000093660
 VIM  BUFFER  get_winopts               73008 0000000000003710
0000000000093710
 VIM  EX_CMDS  do_ecmd                  73749 0000000000005320
00000000000C8280
 VIM  EX_CMDS  getfile                  73467 0000000000004D20
00000000000C7C80
 VIM  TAG  jumpto_tag                   73660 0000000000003F84
000000000019B884
 VIM  TAG  do_tag                       71978 0000000000001520
0000000000198E20
 VIM  EX_DOCMD  do_one_cmd              73971 00000000000024F0
00000000000D9890
 VIM  EX_DOCMD  do_cmdline              72883 0000000000000880
00000000000D7C20
 VIM  NORMAL  nv_colon                  75412 0000000000007AB8
0000000000150F18
 VIM  NORMAL  normal_cmd                72012 00000000000010CC
000000000014A52C
 VIM  MAIN  main_loop                   73183 0000000000002BA0
0000000000110D30
 VIM  MAIN  main                        73034 0000000000002740
00000000001108D0
 VIM  MAIN  __main                          0 0000000000000130
000000000010E2C0
                                            0 FFFFFFFF9D25D3F4
FFFFFFFF9D25D3F4

buffer.lis:
		  72972 /*
		  72973  * Find info for the current window in buffer "buf".
		  72974  * If not found, return the info for the most
recently used window.
		  72975  * Returns NULL when there isn't any info.
		  72976  */
		  72977     static wininfo_T *
		  72978 find_wininfo(buf)
		  72979     buf_T	*buf;
      1	  72980 {
      1	  72981     wininfo_T	*wip;
      1	  72982
      1	  72983     for (wip = buf->b_wininfo; wip != NULL; wip =
wip->wi_next)
Crash!1	  72984 	if (wip->wi_win == curwin)
      1	  72985 	    break;
      1	  72986     if (wip == NULL)	/* if no fpos for curwin, use the
first in the list */
      1	  72987 	wip = buf->b_wininfo;
      1	  72988     return wip;
      1	  72989 }

I added some debugging code to find_wininfo() in buffer.c. See "buffer.lis"
below.
This produces the following stack trace:

TIGER2:CENGELBARTS:M45> gv main.c
%DCL-S-SPAWNED, process CENGELBARTS_1 spawned
TIGER2:CENGELBARTS:M45>

                        curwin = 1E6F40
&wip = 7AE6B048, wip = 1F3F70
&wip->wi_win = 1F3F78
wip->wi_win = 555B3A4B
&wip = 7AE6B048, wip = 52455355
&wip->wi_win = 5245535D
%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual
address=000000005245535D, PC=00000000000831F0, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
  image    module    routine             line      rel PC           abs PC
 VIM  BUFFER  find_wininfo              72989 00000000000031F0
00000000000831F0
 VIM  BUFFER  get_winopts               73015 00000000000032D4
00000000000832D4
 VIM  EX_CMDS  do_ecmd                  73749 0000000000004B30
00000000000B0CF0
 VIM  EX_CMDS  getfile                  73467 00000000000045B0
00000000000B0770
 VIM  TAG  jumpto_tag                   73660 0000000000003BEC
000000000017130C
 VIM  TAG  do_tag                       71978 00000000000014E0
000000000016EC00
 VIM  EX_DOCMD  do_one_cmd              73971 00000000000027FC
00000000000C108C
 VIM  EX_DOCMD  do_cmdline              72883 0000000000000830
00000000000BF0C0
 VIM  NORMAL  nv_colon                  75412 0000000000007434
000000000012CD94
 VIM  NORMAL  normal_cmd                72012 0000000000001080
00000000001269E0
 VIM  MAIN  main_loop                   73183 0000000000002A58
00000000000F2398
 VIM  MAIN  main                        73034 0000000000002610
00000000000F1F50
 VIM  MAIN  __main                          0 0000000000000070
00000000000EF9B0
                                            0 FFFFFFFF9D25D3F4
FFFFFFFF9D25D3F4
TIGER2:CENGELBARTS:M45>

buffer.lis:
	  72972 /*
	  72973  * Find info for the current window in buffer "buf".
	  72974  * If not found, return the info for the most recently used
window.
	  72975  * Returns NULL when there isn't any info.
	  72976  */
	  72977     static wininfo_T *
	  72978 find_wininfo(buf)
	  72979     buf_T	*buf;
      1	  72980 {
      1	  72981     wininfo_T	*wip;
      1	  72982
      1	  72983     fprintf(stderr, "curwin = %p\n", curwin);
/* CE */
      1	  72984     for (wip = buf->b_wininfo; wip != NULL; wip =
wip->wi_next)
      2	  72985     {
/* CE */
      2	  72986         fprintf(stderr, "&wip = %p, wip = %p\n", &wip, wip);
/* CE */
      2	  72987         if(wip != NULL)
/* CE */
      2	  72988             fprintf(stderr, "&wip->wi_win = %p\n",
&wip->wi_win); /* CE */
Crash!2	  72989             fprintf(stderr, "wip->wi_win = %p\n",
wip->wi_win); /* CE */
      2	  72990 	if (wip->wi_win == curwin)
      2	  72991 	    break;
      1	  72992     }
/* CE */
      1	  72993     if (wip == NULL)	/* if no fpos for curwin, use the
first in the list */
      1	  72994 	wip = buf->b_wininfo;
      1	  72995     return wip;
      1	  72996 }

Preliminary conclusion:
Vim crashes in find_wininfo() with an acces violation on address
&wip->wi_win = 5245535D.
I'm not sure if the pointer wip has a bogus value, or if this is a structure
alignment problem.
Note that &wip = 7AE6B048, wip = 52455355. I think, but I'm not sure, that a
valid structure address must end in [048C] on Alpha systems. It also depends
on compiler #pragmas.

And that marks the end of today's rainy vim-debugging-lunch-break. (not the
only one for this particular problem)
Before I spend a lot of time trying to figure out how buf->wininfo etc.
work, I thought I asked your comments.

Thanks for any help,

Coen

---
Vim on VMS discussion list.
Public responses to [email-masked]

Unsubscribe http://www.polarfox.com/vim/