[Message Prev][Message Next][Thread Prev][Thread Next][Message Index][Thread Index]
[MD:2826]Portable dumper
- X-ml-count: 2826
- Subject: [MD:2826]Portable dumper
- From: Keiichiro Nagano (永野圭一郎) <knagano@xxxxxxxxx>
- Date: Fri, 18 Jan 2002 07:02:02 +0900
- User-agent: Wanderlust/2.6.1 (Upside Down) EMY/1.13.9 (Art is long, life is short) SLIM/1.14.7 (酒井彩名) APEL/10.3 Emacs/21.1 (i586-pc-linux-gnulibc1) MULE/5.0 (SAKAKI)
# 林さんの code が面白くて眠れない……
# 朝になってしまった
At 17 Jan 2002 20:00:21 +0900,
Yoshiki Hayashi wrote:
> pdump_relocate_objects に bug があって、mmap の返り値によっ
> て動いたり動かなかったりすることが判明しました。
>
> 永野君の buffer local があやしいかも、というのはあたりで、
> relocate を忘れているのがありました。後、PDUMP_OFFSET を 0
> や 12288 にして MAP_FIXED でむりやりその場所に mmap した場合
> に正しく動かない、という現象があるので、後で debug します。
この修正で、僕の手元でも garbage-collect が動くようになりました!!
ただ、また新たな bug を見つけました。-q -no-site-file で起動して
*scratch* buffer で (category-table) を評価すると、100% SEGV が飛んで
きます。-f category-table では落ちません。backtrace (bt1.txt) が示す通
り、PVEC_CHAR_TABLE を print() しようとして死んでいます。
また、同じような症状で、立ち上げた Emacs 上で M-x garbage-collect を数
回繰り返すと落ちます (bt2.txt)。これは GC で落ちているのではなく、
garbage-collect という symbol の oblookup に失敗しています。こちらは、
何回やれば落ちるのか、といったようなきちんとした再現性を、まだ見付けて
いません。
これらから、何となく、Vectorlike まわりにまだ bug があるのではないかと
いう気がしています。
これだけではなんなので、emacs.dmp を探す code を (XEmacs から丸ごとぱ
くってきて) でっちあげました。林さんの patch 3つのあとにあてて下さい。
注意ですが、この patch をあてると src に移動しなくても起動できるように
なるのですが、起動時の argv[0] を見ているので、emacs 以外では
emacs.dmp を見付けられず、起動できなくなります。つまり、今は temacs や
emacs-20.7.* が使えません。(これどうしましょうか。dump 先の file 名を
ちゃんと決めるのが先かな) なお、林さんの2つ目の patch をあてた時点で、
生成される emacs, emacs-20.7.* は temacs と全く同じものになっています。
なお、添付する2つの backtrace は、両方とも僕の patch を当てて作った
binary から吐かせたものですが、これを当てる前から同じ症状が出ていまし
た。
--
Keiichiro Nagano
Program received signal SIGSEGV, Segmentation fault.
0x08102b7f in print (obj=1074982156, printcharfun=269224088, escapeflag=1)
at print.c:1578
1578 c = XBOOL_VECTOR (obj)->data[i];
(gdb) bt
#0 0x08102b7f in print (obj=1074982156, printcharfun=269224088, escapeflag=1)
at print.c:1578
#1 0x08102fbc in print (obj=1074980588, printcharfun=269224088, escapeflag=1)
at print.c:1683
#2 0x08100c89 in Fprin1 (object=1074980588, printcharfun=269224088)
at print.c:860
#3 0x080f61d2 in Ffuncall (nargs=2, args=0x7ffff0e0) at eval.c:2476
#4 0x08120c01 in Fbyte_code (bytestr=805698120, vector=1074773472, maxdepth=9)
at bytecode.c:433
#5 0x080f673a in funcall_lambda (fun=1074773440, nargs=1,
arg_vector=0x7ffff234) at eval.c:2660
#6 0x080f62a5 in Ffuncall (nargs=2, args=0x7ffff230) at eval.c:2521
#7 0x08120c01 in Fbyte_code (bytestr=805697964, vector=1074773416, maxdepth=2)
at bytecode.c:433
#8 0x080f673a in funcall_lambda (fun=1074773384, nargs=0,
arg_vector=0x7ffff384) at eval.c:2660
#9 0x080f62a5 in Ffuncall (nargs=1, args=0x7ffff380) at eval.c:2521
#10 0x080f5d7e in apply1 (fn=269280776, arg=269224088) at eval.c:2226
#11 0x080f1994 in Fcall_interactively (function=269280776,
record_flag=269224088, keys=1074958992) at callint.c:360
#12 0x080a2d1a in Fcommand_execute (cmd=269280776, record_flag=269224088,
keys=269224088, special=269224088) at keyboard.c:7984
#13 0x0809aef0 in command_loop_1 () at keyboard.c:1502
#14 0x080f43ea in internal_condition_case (bfun=0x809a280 <command_loop_1>,
handlers=269230616, hfun=0x8099ef0 <cmd_error>) at eval.c:1156
#15 0x0809a148 in command_loop_2 () at keyboard.c:1093
#16 0x080f3f5a in internal_catch (tag=269270504,
func=0x809a120 <command_loop_2>, arg=269224088) at eval.c:931
#17 0x0809a0f3 in command_loop () at keyboard.c:1072
#18 0x08099cfe in recursive_edit_1 () at keyboard.c:821
#19 0x08099dfc in Frecursive_edit () at keyboard.c:869
#20 0x08098e7a in main (argc=3, argv=0x7ffffa24, envp=0x7ffffa34)
at emacs.c:1452
#21 0x2aca79ae in __libc_start_main (main=0x8098260 <main>, argc=3,
argv=0x7ffffa24, init=0x804c710 <_init>, fini=0x8131eb0 <_fini>,
rtld_fini=0x2aab66f4 <_dl_fini>, stack_end=0x7ffffa1c)
at ../sysdeps/generic/libc-start.c:92
(gdb) p obj
$11 = 1074982156
(gdb) xtype
Lisp_Vectorlike
PVEC_BOOL_VECTOR
(gdb) p obj
$12 = 1074982156
(gdb) xvector
$13 = (struct Lisp_Vector *) 0x12ed0c
0
(gdb) p obj
$14 = 1074982156
(gdb) xboolvector
$15 = (struct Lisp_Bool_Vector *) 0x12ed0c
0
(gdb) up
#1 0x08102fbc in print (obj=1074980588, printcharfun=269224088, escapeflag=1)
at print.c:1683
1683 print (tem, printcharfun, escapeflag);
(gdb) p obj
$16 = 1074980588
(gdb) xtype
Lisp_Vectorlike
PVEC_CHAR_TABLE
(gdb) p obj
$17 = 1074980588
(gdb) xvector
$18 = (struct Lisp_Vector *) 0x12e6ec
0
(gdb) p obj
$19 = 1074980588
(gdb) xchartable
$20 = (struct Lisp_Char_Table *) 0x12e6ec
Purpose: This context has class, union or enum Lisp_Symbol, not a struct.
(gdb) up
#2 0x08100c89 in Fprin1 (object=1074980588, printcharfun=269224088)
at print.c:860
860 print (object, printcharfun, 1);
(gdb) p object
$21 = 1074980588
(gdb) xtype
Lisp_Vectorlike
PVEC_CHAR_TABLE
(gdb) p object
$22 = 1074980588
(gdb) xvector
$23 = (struct Lisp_Vector *) 0x12e6ec
0
(gdb) p object
$24 = 1074980588
(gdb) xchartable
$25 = (struct Lisp_Char_Table *) 0x12e6ec
Purpose: This context has class, union or enum Lisp_Symbol, not a struct.
(gdb) bt
#0 0x2acae791 in __kill () from /lib/libc.so.6
#1 0x08097c34 in fatal_error_signal (sig=11) at emacs.c:254
#2 <signal handler called>
#3 0x0810766f in oblookup (obarray=1218018696, ptr=0xaf014 "garbage-collect",
size=15, size_byte=15) at lread.c:2736
#4 0x081073c9 in Fintern_soft (string=806023176, obarray=1218018696)
at lread.c:2619
#5 0x080f61d2 in Ffuncall (nargs=3, args=0x7fffe910) at eval.c:2476
#6 0x08120c01 in Fbyte_code (bytestr=949369544, vector=1217795584, maxdepth=3)
at bytecode.c:433
#7 0x080f673a in funcall_lambda (fun=1217795664, nargs=0,
arg_vector=0x7fffea44) at eval.c:2660
#8 0x080f62a5 in Ffuncall (nargs=1, args=0x7fffea40) at eval.c:2521
#9 0x08120c01 in Fbyte_code (bytestr=949369640, vector=1217795792, maxdepth=2)
at bytecode.c:433
#10 0x080f673a in funcall_lambda (fun=1217795872, nargs=0,
arg_vector=0x7fffec28) at eval.c:2660
#11 0x080f62a5 in Ffuncall (nargs=1, args=0x7fffec24) at eval.c:2521
#12 0x080f57b8 in Fapply (nargs=2, args=0x7fffec24) at eval.c:1932
#13 0x080f60f4 in Ffuncall (nargs=3, args=0x7fffec20) at eval.c:2454
#14 0x08120c01 in Fbyte_code (bytestr=949366696, vector=1217054896, maxdepth=4)
at bytecode.c:433
#15 0x080f5506 in Feval (form=1486160036) at eval.c:1837
#16 0x080f42e9 in Fcondition_case (args=1484997836) at eval.c:1105
#17 0x081212c2 in Fbyte_code (bytestr=949366576, vector=1216711032, maxdepth=5)
at bytecode.c:606
#18 0x080f673a in funcall_lambda (fun=1216711168, nargs=1,
arg_vector=0x7fffefe4) at eval.c:2660
#19 0x080f62a5 in Ffuncall (nargs=2, args=0x7fffefe0) at eval.c:2521
#20 0x080f5e20 in call1 (fn=269279576, arg1=1218025000) at eval.c:2270
#21 0x0809d897 in timer_check (do_it_now=1) at keyboard.c:3481
#22 0x0809c9ea in readable_events (do_timers_now=1) at keyboard.c:2719
#23 0x0809f0ca in get_input_pending (addr=0x8817758, do_timers_now=1)
at keyboard.c:5250
#24 0x080a32c5 in detect_input_pending_run_timers (do_display=1)
at keyboard.c:8199
#25 0x0812554e in wait_reading_process_input (time_limit=30, microsecs=0,
read_kbd=268435455, do_display=1) at process.c:2567
#26 0x08051175 in sit_for (sec=30, usec=0, reading=1, display=1,
initial_display=0) at dispnew.c:2452
#27 0x0809bb25 in read_char (commandflag=1, nmaps=2, maps=0x7ffff450,
prev_event=269224088, used_mouse_menu=0x7ffff508) at keyboard.c:2124
#28 0x080a1488 in read_key_sequence (keybuf=0x7ffff590, bufsize=30,
prompt=269224088, dont_downcase_last=0, can_return_switch_frame=1,
fix_current_buffer=1) at keyboard.c:7023
#29 0x0809a56b in command_loop_1 () at keyboard.c:1275
#30 0x080f43ea in internal_condition_case (bfun=0x809a280 <command_loop_1>,
handlers=269230616, hfun=0x8099ef0 <cmd_error>) at eval.c:1156
#31 0x0809a148 in command_loop_2 () at keyboard.c:1093
#32 0x080f3f5a in internal_catch (tag=269270504,
func=0x809a120 <command_loop_2>, arg=269224088) at eval.c:931
---Type <return> to continue, or q <return> to quit---
#33 0x0809a0f3 in command_loop () at keyboard.c:1072
#34 0x08099cfe in recursive_edit_1 () at keyboard.c:821
#35 0x08099dfc in Frecursive_edit () at keyboard.c:869
#36 0x08098e7a in main (argc=1, argv=0x7ffffa84, envp=0x7ffffa8c)
at emacs.c:1452
#37 0x2aca79ae in __libc_start_main (main=0x8098260 <main>, argc=1,
argv=0x7ffffa84, init=0x804c710 <_init>, fini=0x8131eb0 <_fini>,
rtld_fini=0x2aab66f4 <_dl_fini>, stack_end=0x7ffffa7c)
at ../sysdeps/generic/libc-start.c:92
(gdb) frame 3
#3 0x0810766f in oblookup (obarray=1218018696, ptr=0xaf014 "garbage-collect",
size=15, size_byte=15) at lread.c:2736
2736 if (STRING_BYTES (XSYMBOL (tail)->name) == size_byte)
(gdb) p obarray
$1 = 1218018696
(gdb) xtype
Lisp_Vectorlike
PVEC_NORMAL_VECTOR
(gdb) p obarray
$2 = 1218018696
(gdb) xvector
$3 = (struct Lisp_Vector *) 0x8997d88
{412714276, 412714132, 411552588, 411552564, 412713628, 412713164, 412713748,
411552444, 412713700, 412713044, 412714324, 0, 412714420, 412714348,
412714156, 412714060, 412714300, 411552516, 412713212, 411552492, 411552540,
412714372, 412712564, 412713404, 412714204, 412714468, 411552420, 412713092,
412713308, 412714444, 412713260}
diff -ur 020118-2-pdump/src/alloc.c pdump/src/alloc.c
--- src/alloc.c Fri Jan 18 00:20:23 2002
+++ src/alloc.c Fri Jan 18 06:53:02 2002
@@ -3697,20 +3697,25 @@
} \
while (0)
+static int pdump_open_dumped_file (char *argv0);
static void pdump_relocate_objects (long offset);
int
-pdump_load ()
+pdump_load (char *argv0)
{
int i;
- int fd = open ("emacs.dmp", O_RDONLY);
+ int fd;
char *ret;
long offset;
+ if ((fd = pdump_open_dumped_file (argv0)) < 0)
+ return 1;
+
read (fd, &pdump_header, sizeof (pdump_header));
lseek (fd, 0, SEEK_SET);
ret = (char *)mmap (pdump_header.offset, pdump_header.objects_size
+ sizeof (pdump_header_t),
PROT_READ|PROT_WRITE, MAP_PRIVATE,
+
fd, 0);
if ((long) ret == -1)
return 1;
@@ -3956,7 +3961,8 @@
case Lisp_Misc_Buffer_Local_Value:
case Lisp_Misc_Some_Buffer_Local_Value:
{
- struct Lisp_Buffer_Local_Value *ptr = (struct Lisp_Buffer_Local_Value *)obj_ptr;
+ struct Lisp_Buffer_Local_Value *ptr =
+ (struct Lisp_Buffer_Local_Value *)obj_ptr;
PDUMP_RELOCATE (ptr->buffer, offset);
PDUMP_RELOCATE (ptr->frame, offset);
PDUMP_RELOCATE (ptr->realvalue, offset);
@@ -4059,6 +4065,152 @@
}
+/* dumped file search */
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+/* FIXME: this should be marged with emacs.c */
+#ifndef SEPCHAR
+#define SEPCHAR ':'
+#endif
+
+static int
+pdump_file_check_readable (char *filename)
+{
+ struct stat stat_buf;
+ /* fprintf(stderr, "trying dumped file %s...\n", filename); */
+ if (stat (filename, &stat_buf) == 0)
+ if ((stat_buf.st_mode & S_IRUSR) != 0)
+ {
+ /* fprintf(stderr, "trying dumped file %s... ok\n", filename); */
+ return 1;
+ }
+ /* fprintf(stderr, "trying dumped file %s... ng\n", filename); */
+ return 0;
+}
+
+static int
+pdump_find_exe_path (char *argv0, char *exe_path)
+{
+#ifdef WINDOWSNT
+ GetModuleFileName (NULL, exe_path, PATH_MAX);
+#else /* !WINDOWSNT */
+ char *w;
+ const char *dir, *p;
+
+ dir = argv0;
+ if (dir[0] == '-')
+ {
+ /* Emacs as a login shell, how religious! */
+ dir = getenv ("SHELL");
+ }
+
+ p = dir + strlen (dir);
+ while (p != dir && !IS_ANY_SEP (p[-1])) p--;
+
+ if (p != dir)
+ {
+ /* invocation-name includes a directory component -- presumably it
+ is relative to cwd, not $PATH */
+ strcpy (exe_path, dir);
+ }
+ else
+ {
+ const char *path = getenv ("PATH");
+ const char *name = p;
+ for (;;)
+ {
+ p = path;
+ while (*p && *p != SEPCHAR)
+ p++;
+ if (p == path)
+ {
+ exe_path[0] = '.';
+ w = exe_path + 1;
+ }
+ else
+ {
+ memcpy (exe_path, path, p - path);
+ w = exe_path + (p - path);
+ }
+ if (!IS_DIRECTORY_SEP (w[-1]))
+ {
+ *w++ = '/';
+ }
+ strcpy (w, name);
+
+ /* ### #$%$#^$^@%$^#%@$ ! */
+#ifdef access
+#undef access
+#endif
+
+ if (!access (exe_path, X_OK))
+ break;
+ if (!*p)
+ {
+ /* Oh well, let's have some kind of default */
+ sprintf (exe_path, "./%s", name);
+ break;
+ }
+ path = p+1;
+ }
+ }
+#endif /* WINDOWSNT */
+
+ return 1;
+}
+
+static int
+pdump_find_dumped_file (char *exe_path)
+{
+ char *w = exe_path + strlen (exe_path);
+
+ do
+ {
+ /* ### FIXME: the versioning and dump_id are not implemented yet */
+#if 0
+ sprintf (w, "-%s-%08x.dmp", EMACS_VERSION, dump_id);
+ if (pdump_file_check_readable (exe_path))
+ return 1;
+
+ sprintf (w, "-%08x.dmp", dump_id);
+ if (pdump_file_check_readable (exe_path))
+ return 1;
+
+#endif
+ sprintf (w, ".dmp");
+ if (pdump_file_check_readable (exe_path))
+ return 1;
+
+ do
+ w--;
+ while (w > exe_path
+ && !IS_DIRECTORY_SEP (*w)
+ && (*w != '-')
+ && (*w != '.'));
+ }
+ while (w > exe_path && !IS_DIRECTORY_SEP (*w));
+
+ /* ### FIXME: temporal logic; try to find fixed name `emacs.dmp' */
+ sprintf (w+1, "emacs.dmp");
+ if (pdump_file_check_readable (exe_path))
+ return 1;
+
+ return 0;
+}
+
+static int
+pdump_open_dumped_file (char *argv0)
+{
+ char path[PATH_MAX];
+ if (pdump_find_exe_path (argv0, path))
+ if (pdump_find_dumped_file (path))
+ return open(path, O_RDONLY);
+ return -1;
+}
+
+
/* Initialization */
void
diff -ur 020118-2-pdump/src/emacs.c pdump/src/emacs.c
--- src/emacs.c Fri Jan 18 00:20:23 2002
+++ src/emacs.c Fri Jan 18 03:06:35 2002
@@ -1017,7 +1017,7 @@
#ifdef PDUMP
else
{
- if (pdump_load ())
+ if (pdump_load (argv[0]))
{
fprintf (stderr, "emacs: failed to load dumped file\n");
exit (1);