handle_event.c revision 44965c7a1d3106439b20e8f36307f506df3df44b
1#define _GNU_SOURCE
2#include "config.h"
3
4#include <stdio.h>
5#include <string.h>
6#include <stdlib.h>
7#include <signal.h>
8#include <assert.h>
9#include <sys/time.h>
10#include <errno.h>
11
12#ifdef __powerpc__
13#include <sys/ptrace.h>
14#endif
15
16#include "common.h"
17#include "breakpoint.h"
18#include "proc.h"
19#include "library.h"
20
21static void handle_signal(Event *event);
22static void handle_exit(Event *event);
23static void handle_exit_signal(Event *event);
24static void handle_syscall(Event *event);
25static void handle_arch_syscall(Event *event);
26static void handle_sysret(Event *event);
27static void handle_arch_sysret(Event *event);
28static void handle_clone(Event *event);
29static void handle_exec(Event *event);
30static void handle_breakpoint(Event *event);
31static void handle_new(Event *event);
32
33static void callstack_push_syscall(Process *proc, int sysnum);
34static void callstack_push_symfunc(Process *proc,
35				   struct library_symbol *sym);
36static void callstack_pop(Process *proc);
37
38static char * shortsignal(Process *proc, int signum);
39static char * sysname(Process *proc, int sysnum);
40static char * arch_sysname(Process *proc, int sysnum);
41
42static Event *
43call_handler(Process * proc, Event * event)
44{
45	assert(proc != NULL);
46
47	struct event_handler *handler = proc->event_handler;
48	if (handler == NULL)
49		return event;
50
51	return (*handler->on_event) (handler, event);
52}
53
54void
55handle_event(Event *event)
56{
57	if (exiting == 1) {
58		debug(1, "ltrace about to exit");
59		os_ltrace_exiting();
60		exiting = 2;
61	}
62	debug(DEBUG_FUNCTION, "handle_event(pid=%d, type=%d)",
63	      event->proc ? event->proc->pid : -1, event->type);
64
65	/* If the thread group or an individual task define an
66	   overriding event handler, give them a chance to kick in.
67	   We will end up calling both handlers, if the first one
68	   doesn't sink the event.  */
69	if (event->proc != NULL) {
70		event = call_handler(event->proc, event);
71		if (event == NULL)
72			/* It was handled.  */
73			return;
74
75		/* Note: the previous handler has a chance to alter
76		 * the event.  */
77		if (event->proc != NULL
78		    && event->proc->leader != NULL
79		    && event->proc != event->proc->leader) {
80			event = call_handler(event->proc->leader, event);
81			if (event == NULL)
82				return;
83		}
84	}
85
86	switch (event->type) {
87	case EVENT_NONE:
88		debug(1, "event: none");
89		return;
90	case EVENT_SIGNAL:
91		debug(1, "event: signal (%s [%d])",
92		      shortsignal(event->proc, event->e_un.signum),
93		      event->e_un.signum);
94		handle_signal(event);
95		return;
96	case EVENT_EXIT:
97		debug(1, "event: exit (%d)", event->e_un.ret_val);
98		handle_exit(event);
99		return;
100	case EVENT_EXIT_SIGNAL:
101		debug(1, "event: exit signal (%s [%d])",
102		      shortsignal(event->proc, event->e_un.signum),
103		      event->e_un.signum);
104		handle_exit_signal(event);
105		return;
106	case EVENT_SYSCALL:
107		debug(1, "event: syscall (%s [%d])",
108		      sysname(event->proc, event->e_un.sysnum),
109		      event->e_un.sysnum);
110		handle_syscall(event);
111		return;
112	case EVENT_SYSRET:
113		debug(1, "event: sysret (%s [%d])",
114		      sysname(event->proc, event->e_un.sysnum),
115		      event->e_un.sysnum);
116		handle_sysret(event);
117		return;
118	case EVENT_ARCH_SYSCALL:
119		debug(1, "event: arch_syscall (%s [%d])",
120				arch_sysname(event->proc, event->e_un.sysnum),
121				event->e_un.sysnum);
122		handle_arch_syscall(event);
123		return;
124	case EVENT_ARCH_SYSRET:
125		debug(1, "event: arch_sysret (%s [%d])",
126				arch_sysname(event->proc, event->e_un.sysnum),
127				event->e_un.sysnum);
128		handle_arch_sysret(event);
129		return;
130	case EVENT_CLONE:
131	case EVENT_VFORK:
132		debug(1, "event: clone (%u)", event->e_un.newpid);
133		handle_clone(event);
134		return;
135	case EVENT_EXEC:
136		debug(1, "event: exec()");
137		handle_exec(event);
138		return;
139	case EVENT_BREAKPOINT:
140		debug(1, "event: breakpoint");
141		handle_breakpoint(event);
142		return;
143	case EVENT_NEW:
144		debug(1, "event: new process");
145		handle_new(event);
146		return;
147	default:
148		fprintf(stderr, "Error! unknown event?\n");
149		exit(1);
150	}
151}
152
153typedef struct Pending_New Pending_New;
154struct Pending_New {
155	pid_t pid;
156	Pending_New * next;
157};
158static Pending_New * pending_news = NULL;
159
160static int
161pending_new(pid_t pid) {
162	Pending_New * p;
163
164	debug(DEBUG_FUNCTION, "pending_new(%d)", pid);
165
166	p = pending_news;
167	while (p) {
168		if (p->pid == pid) {
169			return 1;
170		}
171		p = p->next;
172	}
173	return 0;
174}
175
176static void
177pending_new_insert(pid_t pid) {
178	Pending_New * p;
179
180	debug(DEBUG_FUNCTION, "pending_new_insert(%d)", pid);
181
182	p = malloc(sizeof(Pending_New));
183	if (!p) {
184		perror("malloc()");
185		exit(1);
186	}
187	p->pid = pid;
188	p->next = pending_news;
189	pending_news = p;
190}
191
192static void
193pending_new_remove(pid_t pid) {
194	Pending_New *p, *pred;
195
196	debug(DEBUG_FUNCTION, "pending_new_remove(%d)", pid);
197
198	p = pending_news;
199	if (p->pid == pid) {
200		pending_news = p->next;
201		free(p);
202	} else {
203		while (p) {
204			if (p->pid == pid) {
205				pred->next = p->next;
206				free(p);
207			}
208			pred = p;
209			p = p->next;
210		}
211	}
212}
213
214#if 0
215static int
216clone_breakpoints(Process * proc, Process * orig_proc)
217{
218	/* When copying breakpoints, we also have to copy the
219	 * referenced symbols, and link them properly.  */
220	Dict * map = dict_init(&dict_key2hash_int, &dict_key_cmp_int);
221	struct library_symbol * it = proc->list_of_symbols;
222	proc->list_of_symbols = NULL;
223	for (; it != NULL; it = it->next) {
224		struct library_symbol * libsym = clone_library_symbol(it);
225		if (libsym == NULL) {
226			int save_errno;
227		err:
228			save_errno = errno;
229			destroy_library_symbol_chain(proc->list_of_symbols);
230			dict_clear(map);
231			errno = save_errno;
232			return -1;
233		}
234		libsym->next = proc->list_of_symbols;
235		proc->list_of_symbols = libsym;
236		if (dict_enter(map, it, libsym) != 0)
237			goto err;
238	}
239
240	proc->breakpoints = dict_clone2(orig_proc->breakpoints,
241					address_clone, breakpoint_clone, map);
242	if (proc->breakpoints == NULL)
243		goto err;
244
245	dict_clear(map);
246	return 0;
247}
248#endif
249
250static void
251handle_clone(Event *event)
252{
253	debug(DEBUG_FUNCTION, "handle_clone(pid=%d)", event->proc->pid);
254
255	struct Process *proc = malloc(sizeof(*proc));
256	if (proc == NULL) {
257	fail:
258		free(proc);
259		/* XXX proper error handling here, please.  */
260		perror("malloc()");
261		exit(1);
262	}
263
264	if (process_clone(proc, event->proc, event->e_un.newpid) < 0)
265		goto fail;
266	proc->parent = event->proc;
267
268	/* We save register values to the arch pointer, and these need
269	   to be per-thread.  */
270	proc->arch_ptr = NULL;
271
272	if (pending_new(proc->pid)) {
273		pending_new_remove(proc->pid);
274		/* XXX this used to be destroy_event_handler call, but
275		 * I don't think we want to call that on a shared
276		 * state.  */
277		proc->event_handler = NULL;
278		if (event->proc->state == STATE_ATTACHED && options.follow)
279			proc->state = STATE_ATTACHED;
280		else
281			proc->state = STATE_IGNORED;
282		continue_process(proc->pid);
283	} else {
284		proc->state = STATE_BEING_CREATED;
285	}
286
287	if (event->type == EVENT_VFORK)
288		continue_after_vfork(proc);
289	else
290		continue_process(event->proc->pid);
291}
292
293static void
294handle_new(Event * event) {
295	Process * proc;
296
297	debug(DEBUG_FUNCTION, "handle_new(pid=%d)", event->e_un.newpid);
298
299	proc = pid2proc(event->e_un.newpid);
300	if (!proc) {
301		pending_new_insert(event->e_un.newpid);
302	} else {
303		assert(proc->state == STATE_BEING_CREATED);
304		if (options.follow) {
305			proc->state = STATE_ATTACHED;
306		} else {
307			proc->state = STATE_IGNORED;
308		}
309		continue_process(proc->pid);
310	}
311}
312
313static char *
314shortsignal(Process *proc, int signum) {
315	static char *signalent0[] = {
316#include "signalent.h"
317	};
318	static char *signalent1[] = {
319#include "signalent1.h"
320	};
321	static char **signalents[] = { signalent0, signalent1 };
322	int nsignals[] = { sizeof signalent0 / sizeof signalent0[0],
323		sizeof signalent1 / sizeof signalent1[0]
324	};
325
326	debug(DEBUG_FUNCTION, "shortsignal(pid=%d, signum=%d)", proc->pid, signum);
327
328	if (proc->personality > sizeof signalents / sizeof signalents[0])
329		abort();
330	if (signum < 0 || signum >= nsignals[proc->personality]) {
331		return "UNKNOWN_SIGNAL";
332	} else {
333		return signalents[proc->personality][signum];
334	}
335}
336
337static char *
338sysname(Process *proc, int sysnum) {
339	static char result[128];
340	static char *syscalent0[] = {
341#include "syscallent.h"
342	};
343	static char *syscalent1[] = {
344#include "syscallent1.h"
345	};
346	static char **syscalents[] = { syscalent0, syscalent1 };
347	int nsyscals[] = { sizeof syscalent0 / sizeof syscalent0[0],
348		sizeof syscalent1 / sizeof syscalent1[0]
349	};
350
351	debug(DEBUG_FUNCTION, "sysname(pid=%d, sysnum=%d)", proc->pid, sysnum);
352
353	if (proc->personality > sizeof syscalents / sizeof syscalents[0])
354		abort();
355	if (sysnum < 0 || sysnum >= nsyscals[proc->personality]) {
356		sprintf(result, "SYS_%d", sysnum);
357		return result;
358	} else {
359		sprintf(result, "SYS_%s",
360			syscalents[proc->personality][sysnum]);
361		return result;
362	}
363}
364
365static char *
366arch_sysname(Process *proc, int sysnum) {
367	static char result[128];
368	static char *arch_syscalent[] = {
369#include "arch_syscallent.h"
370	};
371	int nsyscals = sizeof arch_syscalent / sizeof arch_syscalent[0];
372
373	debug(DEBUG_FUNCTION, "arch_sysname(pid=%d, sysnum=%d)", proc->pid, sysnum);
374
375	if (sysnum < 0 || sysnum >= nsyscals) {
376		sprintf(result, "ARCH_%d", sysnum);
377		return result;
378	} else {
379		sprintf(result, "ARCH_%s",
380				arch_syscalent[sysnum]);
381		return result;
382	}
383}
384
385static void
386handle_signal(Event *event) {
387	debug(DEBUG_FUNCTION, "handle_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
388	if (event->proc->state != STATE_IGNORED && !options.no_signals) {
389		output_line(event->proc, "--- %s (%s) ---",
390				shortsignal(event->proc, event->e_un.signum),
391				strsignal(event->e_un.signum));
392	}
393	continue_after_signal(event->proc->pid, event->e_un.signum);
394}
395
396static void
397handle_exit(Event *event) {
398	debug(DEBUG_FUNCTION, "handle_exit(pid=%d, status=%d)", event->proc->pid, event->e_un.ret_val);
399	if (event->proc->state != STATE_IGNORED) {
400		output_line(event->proc, "+++ exited (status %d) +++",
401				event->e_un.ret_val);
402	}
403	remove_process(event->proc);
404	free(event->proc);
405}
406
407static void
408handle_exit_signal(Event *event) {
409	debug(DEBUG_FUNCTION, "handle_exit_signal(pid=%d, signum=%d)", event->proc->pid, event->e_un.signum);
410	if (event->proc->state != STATE_IGNORED) {
411		output_line(event->proc, "+++ killed by %s +++",
412				shortsignal(event->proc, event->e_un.signum));
413	}
414	remove_process(event->proc);
415	free(event->proc);
416}
417
418static struct library_symbol *
419temporary_syscall_symbol(const char *name)
420{
421	struct library *syscalls = malloc(sizeof(*syscalls));
422	struct library_symbol *syscall = malloc(sizeof(*syscall));
423	if (syscalls == NULL || syscall == NULL) {
424		free(syscalls);
425		free(syscall);
426		return NULL;
427	}
428	library_init(syscalls, (enum library_type)-1);
429	library_set_soname(syscalls, "SYS", 0);
430	library_symbol_init(syscall, 0, name, 0, LS_TOPLT_NONE);
431	library_add_symbol(syscalls, syscall);
432	return syscall;
433}
434
435static void
436output_syscall_left(struct Process *proc, const char *name)
437{
438	struct library_symbol *syscall = temporary_syscall_symbol(name);
439	output_left(LT_TOF_SYSCALL, proc, syscall);
440	struct library *lib = syscall->lib;
441	library_destroy(lib);
442	free(lib);
443}
444
445static void
446output_syscall_right(struct Process *proc, const char *name)
447{
448	struct library_symbol *syscall = temporary_syscall_symbol(name);
449	output_right(LT_TOF_SYSCALLR, proc, syscall);
450	struct library *lib = syscall->lib;
451	library_destroy(lib);
452	free(lib);
453}
454
455static void
456handle_syscall(Event *event) {
457	debug(DEBUG_FUNCTION, "handle_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
458	if (event->proc->state != STATE_IGNORED) {
459		callstack_push_syscall(event->proc, event->e_un.sysnum);
460		if (options.syscalls)
461			output_syscall_left(event->proc,
462					    sysname(event->proc,
463						    event->e_un.sysnum));
464	}
465	continue_after_syscall(event->proc, event->e_un.sysnum, 0);
466}
467
468static void
469handle_exec(Event * event) {
470	Process * proc = event->proc;
471
472	debug(DEBUG_FUNCTION, "handle_exec(pid=%d)", proc->pid);
473	if (proc->state == STATE_IGNORED) {
474		untrace_pid(proc->pid);
475		remove_process(proc);
476		free(proc);
477		return;
478	}
479	output_line(proc, "--- Called exec() ---");
480	proc->mask_32bit = 0;
481	proc->personality = 0;
482	proc->arch_ptr = NULL;
483	free(proc->filename);
484	proc->filename = pid2name(proc->pid);
485	breakpoints_init(proc, 0);
486	proc->callstack_depth = 0;
487	continue_process(proc->pid);
488}
489
490static void
491handle_arch_syscall(Event *event) {
492	debug(DEBUG_FUNCTION, "handle_arch_syscall(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
493	if (event->proc->state != STATE_IGNORED) {
494		callstack_push_syscall(event->proc, 0xf0000 + event->e_un.sysnum);
495		if (options.syscalls) {
496			output_syscall_left(event->proc,
497					    arch_sysname(event->proc,
498							 event->e_un.sysnum));
499		}
500	}
501	continue_process(event->proc->pid);
502}
503
504struct timeval current_time_spent;
505
506static void
507calc_time_spent(Process *proc) {
508	struct timeval tv;
509	struct timezone tz;
510	struct timeval diff;
511	struct callstack_element *elem;
512
513	debug(DEBUG_FUNCTION, "calc_time_spent(pid=%d)", proc->pid);
514	elem = &proc->callstack[proc->callstack_depth - 1];
515
516	gettimeofday(&tv, &tz);
517
518	diff.tv_sec = tv.tv_sec - elem->time_spent.tv_sec;
519	if (tv.tv_usec >= elem->time_spent.tv_usec) {
520		diff.tv_usec = tv.tv_usec - elem->time_spent.tv_usec;
521	} else {
522		diff.tv_sec++;
523		diff.tv_usec = 1000000 + tv.tv_usec - elem->time_spent.tv_usec;
524	}
525	current_time_spent = diff;
526}
527
528static void
529handle_sysret(Event *event) {
530	debug(DEBUG_FUNCTION, "handle_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
531	if (event->proc->state != STATE_IGNORED) {
532		if (opt_T || options.summary) {
533			calc_time_spent(event->proc);
534		}
535		if (options.syscalls)
536			output_syscall_right(event->proc,
537					     sysname(event->proc,
538						     event->e_un.sysnum));
539
540		assert(event->proc->callstack_depth > 0);
541		unsigned d = event->proc->callstack_depth - 1;
542		assert(event->proc->callstack[d].is_syscall);
543		callstack_pop(event->proc);
544	}
545	continue_after_syscall(event->proc, event->e_un.sysnum, 1);
546}
547
548static void
549handle_arch_sysret(Event *event) {
550	debug(DEBUG_FUNCTION, "handle_arch_sysret(pid=%d, sysnum=%d)", event->proc->pid, event->e_un.sysnum);
551	if (event->proc->state != STATE_IGNORED) {
552		if (opt_T || options.summary) {
553			calc_time_spent(event->proc);
554		}
555		if (options.syscalls)
556			output_syscall_right(event->proc,
557					     arch_sysname(event->proc,
558							  event->e_un.sysnum));
559		callstack_pop(event->proc);
560	}
561	continue_process(event->proc->pid);
562}
563
564static void
565output_right_tos(struct Process *proc)
566{
567	size_t d = proc->callstack_depth;
568	struct callstack_element *elem = &proc->callstack[d - 1];
569	if (proc->state != STATE_IGNORED)
570		output_right(LT_TOF_FUNCTIONR, proc, elem->c_un.libfunc->name);
571}
572
573static void
574handle_breakpoint(Event *event)
575{
576	int i, j;
577	struct breakpoint *sbp;
578	Process *leader = event->proc->leader;
579	void *brk_addr = event->e_un.brk_addr;
580
581	/* The leader has terminated.  */
582	if (leader == NULL) {
583		continue_process(event->proc->pid);
584		return;
585	}
586
587	debug(DEBUG_FUNCTION, "handle_breakpoint(pid=%d, addr=%p)",
588	      event->proc->pid, brk_addr);
589	debug(2, "event: breakpoint (%p)", brk_addr);
590
591	for (i = event->proc->callstack_depth - 1; i >= 0; i--) {
592		if (brk_addr == event->proc->callstack[i].return_addr) {
593#if defined(__mips__)
594			void *addr = NULL;
595			struct library_symbol *sym= event->proc->callstack[i].c_un.libfunc;
596			struct library_symbol *new_sym;
597			assert(sym);
598			addr = sym2addr(event->proc, sym);
599			sbp = dict_find_entry(leader->breakpoints, addr);
600			if (sbp) {
601				if (addr != sbp->addr) {
602					insert_breakpoint(event->proc, addr, sym);
603				}
604			} else {
605				new_sym=malloc(sizeof(*new_sym) + strlen(sym->name) + 1);
606				memcpy(new_sym,sym,sizeof(*new_sym) + strlen(sym->name) + 1);
607				new_sym->next = leader->list_of_symbols;
608				leader->list_of_symbols = new_sym;
609				insert_breakpoint(event->proc, addr, new_sym);
610			}
611#endif
612			for (j = event->proc->callstack_depth - 1; j > i; j--) {
613				callstack_pop(event->proc);
614			}
615			if (event->proc->state != STATE_IGNORED) {
616				if (opt_T || options.summary) {
617					calc_time_spent(event->proc);
618				}
619			}
620			event->proc->return_addr = brk_addr;
621
622			output_right_tos(event->proc);
623			callstack_pop(event->proc);
624
625			/* Pop also any other entries that seem like
626			 * they are linked to the current one: they
627			 * have the same return address, but were made
628			 * for different symbols.  This should only
629			 * happen for entry point tracing, i.e. for -x
630			 * everywhere, or -x and -e on PPC64.  */
631			while (event->proc->callstack_depth > 0) {
632				struct callstack_element *prev;
633				size_t d = event->proc->callstack_depth;
634				prev = &event->proc->callstack[d - 1];
635
636				if (prev->c_un.libfunc == libsym
637				    || prev->return_addr != brk_addr)
638					break;
639
640				output_right_tos(event->proc);
641				callstack_pop(event->proc);
642			}
643
644			sbp = address2bpstruct(leader, brk_addr);
645			continue_after_breakpoint(event->proc, sbp);
646			return;
647		}
648	}
649
650	if ((sbp = address2bpstruct(leader, brk_addr))) {
651		breakpoint_on_hit(sbp, event->proc);
652
653		if (event->proc->state != STATE_IGNORED
654		    && sbp->libsym != NULL) {
655			event->proc->stack_pointer = get_stack_pointer(event->proc);
656			event->proc->return_addr =
657				get_return_addr(event->proc, event->proc->stack_pointer);
658			callstack_push_symfunc(event->proc, sbp->libsym);
659			output_left(LT_TOF_FUNCTION, event->proc, sbp->libsym);
660		}
661
662		breakpoint_on_continue(sbp, event->proc);
663		return;
664	}
665
666	if (event->proc->state != STATE_IGNORED)
667		output_line(event->proc, "unexpected breakpoint at %p",
668			    brk_addr);
669
670	continue_process(event->proc->pid);
671}
672
673static void
674callstack_push_syscall(Process *proc, int sysnum) {
675	struct callstack_element *elem;
676
677	debug(DEBUG_FUNCTION, "callstack_push_syscall(pid=%d, sysnum=%d)", proc->pid, sysnum);
678	/* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
679	if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
680		fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
681		abort();
682		return;
683	}
684
685	elem = &proc->callstack[proc->callstack_depth];
686	elem->is_syscall = 1;
687	elem->c_un.syscall = sysnum;
688	elem->return_addr = NULL;
689
690	proc->callstack_depth++;
691	if (opt_T || options.summary) {
692		struct timezone tz;
693		gettimeofday(&elem->time_spent, &tz);
694	}
695}
696
697static void
698callstack_push_symfunc(Process *proc, struct library_symbol *sym) {
699	struct callstack_element *elem;
700
701	debug(DEBUG_FUNCTION, "callstack_push_symfunc(pid=%d, symbol=%s)", proc->pid, sym->name);
702	/* FIXME: not good -- should use dynamic allocation. 19990703 mortene. */
703	if (proc->callstack_depth == MAX_CALLDEPTH - 1) {
704		fprintf(stderr, "%s: Error: call nesting too deep!\n", __func__);
705		abort();
706		return;
707	}
708
709	elem = &proc->callstack[proc->callstack_depth++];
710	elem->is_syscall = 0;
711	elem->c_un.libfunc = sym;
712
713	elem->return_addr = proc->return_addr;
714	if (elem->return_addr)
715		insert_breakpoint(proc, elem->return_addr, NULL);
716
717	/* handle functions like atexit() on mips which have no return */
718	if (opt_T || options.summary) {
719		struct timezone tz;
720		gettimeofday(&elem->time_spent, &tz);
721	}
722}
723
724static void
725callstack_pop(Process *proc) {
726	struct callstack_element *elem;
727	assert(proc->callstack_depth > 0);
728
729	debug(DEBUG_FUNCTION, "callstack_pop(pid=%d)", proc->pid);
730	elem = &proc->callstack[proc->callstack_depth - 1];
731	if (!elem->is_syscall && elem->return_addr) {
732		assert(proc->leader != NULL);
733		delete_breakpoint(proc, elem->return_addr);
734	}
735	if (elem->arch_ptr != NULL) {
736		free(elem->arch_ptr);
737		elem->arch_ptr = NULL;
738	}
739	proc->callstack_depth--;
740}
741