[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: problem report #97: base/src/emacs/src/term.c (init_tty): RESOURCE_L
From: |
Dan Nicolaescu |
Subject: |
Re: problem report #97: base/src/emacs/src/term.c (init_tty): RESOURCE_LEAK |
Date: |
Sun, 7 Dec 2008 23:07:49 -0800 (PST) |
Dan Nicolaescu <address@hidden> writes:
> CID: 97
> Checker: RESOURCE_LEAK (help)
> File: base/src/emacs/src/term.c
> Function: init_tty
> Description: Returned without freeing storage "area"
>
> Event alloc_fn: Called allocation function "xmalloc" [model]
> Event var_assign: Assigned variable "area" to storage returned from
"xmalloc"
> Also see events: [var_assign][leaked_storage]
>
> 3555 area = (char *) xmalloc (buffer_size);
> 3556
> 3557 tty->TS_ins_line = tgetstr ("al", address);
> 3558 tty->TS_ins_multi_lines = tgetstr ("AL", address);
> 3559 tty->TS_bell = tgetstr ("bl", address);
> 3560 BackTab (tty) = tgetstr ("bt", address);
> 3561 tty->TS_clr_to_bottom = tgetstr ("cd", address);
> 3562 tty->TS_clr_line = tgetstr ("ce", address);
> 3563 tty->TS_clr_frame = tgetstr ("cl", address);
> 3564 ColPosition (tty) = NULL; /* tgetstr ("ch", address); */
> 3565 AbsPosition (tty) = tgetstr ("cm", address);
> 3566 CR (tty) = tgetstr ("cr", address);
> 3567 tty->TS_set_scroll_region = tgetstr ("cs", address);
> 3568 tty->TS_set_scroll_region_1 = tgetstr ("cS", address);
> 3569 RowPosition (tty) = tgetstr ("cv", address);
> 3570 tty->TS_del_char = tgetstr ("dc", address);
> 3571 tty->TS_del_multi_chars = tgetstr ("DC", address);
> 3572 tty->TS_del_line = tgetstr ("dl", address);
> 3573 tty->TS_del_multi_lines = tgetstr ("DL", address);
> 3574 tty->TS_delete_mode = tgetstr ("dm", address);
> 3575 tty->TS_end_delete_mode = tgetstr ("ed", address);
> 3576 tty->TS_end_insert_mode = tgetstr ("ei", address);
> 3577 Home (tty) = tgetstr ("ho", address);
> 3578 tty->TS_ins_char = tgetstr ("ic", address);
> 3579 tty->TS_ins_multi_chars = tgetstr ("IC", address);
> 3580 tty->TS_insert_mode = tgetstr ("im", address);
> 3581 tty->TS_pad_inserted_char = tgetstr ("ip", address);
> 3582 tty->TS_end_keypad_mode = tgetstr ("ke", address);
> 3583 tty->TS_keypad_mode = tgetstr ("ks", address);
> 3584 LastLine (tty) = tgetstr ("ll", address);
> 3585 Right (tty) = tgetstr ("nd", address);
> 3586 Down (tty) = tgetstr ("do", address);
> 3587 if (!Down (tty))
> 3588 Down (tty) = tgetstr ("nl", address); /* Obsolete name for
"do" */
> 3589 if (tgetflag ("bs"))
> 3590 Left (tty) = "\b"; /* can't possibly be longer!
*/
> 3591 else /* (Actually, "bs" is
obsolete...) */
> 3592 Left (tty) = tgetstr ("le", address);
> 3593 if (!Left (tty))
> 3594 Left (tty) = tgetstr ("bc", address); /* Obsolete name for
"le" */
> 3595 tty->TS_pad_char = tgetstr ("pc", address);
> 3596 tty->TS_repeat = tgetstr ("rp", address);
> 3597 tty->TS_end_standout_mode = tgetstr ("se", address);
> 3598 tty->TS_fwd_scroll = tgetstr ("sf", address);
> 3599 tty->TS_standout_mode = tgetstr ("so", address);
> 3600 tty->TS_rev_scroll = tgetstr ("sr", address);
> 3601 tty->Wcm->cm_tab = tgetstr ("ta", address);
> 3602 tty->TS_end_termcap_modes = tgetstr ("te", address);
> 3603 tty->TS_termcap_modes = tgetstr ("ti", address);
> 3604 Up (tty) = tgetstr ("up", address);
> 3605 tty->TS_visible_bell = tgetstr ("vb", address);
> 3606 tty->TS_cursor_normal = tgetstr ("ve", address);
> 3607 tty->TS_cursor_visible = tgetstr ("vs", address);
> 3608 tty->TS_cursor_invisible = tgetstr ("vi", address);
> 3609 tty->TS_set_window = tgetstr ("wi", address);
> 3610
> 3611 tty->TS_enter_underline_mode = tgetstr ("us", address);
> 3612 tty->TS_exit_underline_mode = tgetstr ("ue", address);
> 3613 tty->TS_enter_bold_mode = tgetstr ("md", address);
> 3614 tty->TS_enter_dim_mode = tgetstr ("mh", address);
> 3615 tty->TS_enter_blink_mode = tgetstr ("mb", address);
> 3616 tty->TS_enter_reverse_mode = tgetstr ("mr", address);
> 3617 tty->TS_enter_alt_charset_mode = tgetstr ("as", address);
> 3618 tty->TS_exit_alt_charset_mode = tgetstr ("ae", address);
> 3619 tty->TS_exit_attribute_mode = tgetstr ("me", address);
> 3620
> 3621 MultiUp (tty) = tgetstr ("UP", address);
> 3622 MultiDown (tty) = tgetstr ("DO", address);
> 3623 MultiLeft (tty) = tgetstr ("LE", address);
> 3624 MultiRight (tty) = tgetstr ("RI", address);
> 3625
> 3626 /* SVr4/ANSI color suppert. If "op" isn't available, don't
support
> 3627 color because we can't switch back to the default
foreground and
> 3628 background. */
> 3629 tty->TS_orig_pair = tgetstr ("op", address);
> 3630 if (tty->TS_orig_pair)
> 3631 {
> 3632 tty->TS_set_foreground = tgetstr ("AF", address);
> 3633 tty->TS_set_background = tgetstr ("AB", address);
> 3634 if (!tty->TS_set_foreground)
> 3635 {
> 3636 /* SVr4. */
> 3637 tty->TS_set_foreground = tgetstr ("Sf", address);
> 3638 tty->TS_set_background = tgetstr ("Sb", address);
> 3639 }
> 3640
> 3641 tty->TN_max_colors = tgetnum ("Co");
> 3642 tty->TN_max_pairs = tgetnum ("pa");
> 3643
> 3644 tty->TN_no_color_video = tgetnum ("NC");
> 3645 if (tty->TN_no_color_video == -1)
> 3646 tty->TN_no_color_video = 0;
> 3647 }
> 3648
> 3649 tty_default_color_capabilities (tty, 1);
> 3650
> 3651 MagicWrap (tty) = tgetflag ("xn");
> 3652 /* Since we make MagicWrap terminals look like AutoWrap, we
need to have
> 3653 the former flag imply the latter. */
> 3654 AutoWrap (tty) = MagicWrap (tty) || tgetflag ("am");
> 3655 terminal->memory_below_frame = tgetflag ("db");
> 3656 tty->TF_hazeltine = tgetflag ("hz");
> 3657 terminal->must_write_spaces = tgetflag ("in");
> 3658 tty->meta_key = tgetflag ("km") || tgetflag ("MT");
> 3659 tty->TF_insmode_motion = tgetflag ("mi");
> 3660 tty->TF_standout_motion = tgetflag ("ms");
> 3661 tty->TF_underscore = tgetflag ("ul");
> 3662 tty->TF_teleray = tgetflag ("xt");
> 3663
> 3664 #endif /* !DOS_NT */
> 3665 terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
> 3666 init_kboard (terminal->kboard);
> 3667 terminal->kboard->Vwindow_system = Qnil;
> 3668 terminal->kboard->next_kboard = all_kboards;
> 3669 all_kboards = terminal->kboard;
> 3670 terminal->kboard->reference_count++;
> 3671 /* Don't let the initial kboard remain current longer than
necessary.
> 3672 That would cause problems if a file loaded on startup
tries to
> 3673 prompt in the mini-buffer. */
> 3674 if (current_kboard == initial_kboard)
> 3675 current_kboard = terminal->kboard;
> 3676 #ifndef DOS_NT
> 3677 term_get_fkeys (address, terminal->kboard);
> 3678
> 3679 /* Get frame size from system, or else from termcap. */
> 3680 {
> 3681 int height, width;
> 3682 get_tty_size (fileno (tty->input), &width, &height);
> 3683 FrameCols (tty) = width;
> 3684 FrameRows (tty) = height;
> 3685 }
> 3686
> 3687 if (FrameCols (tty) <= 0)
> 3688 FrameCols (tty) = tgetnum ("co");
> 3689 if (FrameRows (tty) <= 0)
> 3690 FrameRows (tty) = tgetnum ("li");
> 3691
> 3692 if (FrameRows (tty) < 3 || FrameCols (tty) < 3)
> 3693 maybe_fatal (must_succeed, NULL, terminal,
> 3694 "Screen size %dx%d is too small"
> 3695 "Screen size %dx%d is too small",
> 3696 FrameCols (tty), FrameRows (tty));
> 3697
> 3698 #if 0 /* This is not used anywhere. */
> 3699 tty->terminal->min_padding_speed = tgetnum ("pb");
> 3700 #endif
> 3701
> 3702 TabWidth (tty) = tgetnum ("tw");
> 3703
> 3704 if (!tty->TS_bell)
> 3705 tty->TS_bell = "\07";
> 3706
> 3707 if (!tty->TS_fwd_scroll)
> 3708 tty->TS_fwd_scroll = Down (tty);
> 3709
> 3710 PC = tty->TS_pad_char ? *tty->TS_pad_char : 0;
> 3711
> 3712 if (TabWidth (tty) < 0)
> 3713 TabWidth (tty) = 8;
> 3714
> 3715 /* Turned off since /etc/termcap seems to have :ta= for most
terminals
> 3716 and newer termcap doc does not seem to say there is a
default.
> 3717 if (!tty->Wcm->cm_tab)
> 3718 tty->Wcm->cm_tab = "\t";
> 3719 */
> 3720
> 3721 /* We don't support standout modes that use `magic cookies',
so
> 3722 turn off any that do. */
> 3723 if (tty->TS_standout_mode && tgetnum ("sg") >= 0)
> 3724 {
> 3725 tty->TS_standout_mode = 0;
> 3726 tty->TS_end_standout_mode = 0;
> 3727 }
> 3728 if (tty->TS_enter_underline_mode && tgetnum ("ug") >= 0)
> 3729 {
> 3730 tty->TS_enter_underline_mode = 0;
> 3731 tty->TS_exit_underline_mode = 0;
> 3732 }
> 3733
> 3734 /* If there's no standout mode, try to use underlining
instead. */
> 3735 if (tty->TS_standout_mode == 0)
> 3736 {
> 3737 tty->TS_standout_mode = tty->TS_enter_underline_mode;
> 3738 tty->TS_end_standout_mode = tty->TS_exit_underline_mode;
> 3739 }
> 3740
> 3741 /* If no `se' string, try using a `me' string instead.
> 3742 If that fails, we can't use standout mode at all. */
> 3743 if (tty->TS_end_standout_mode == 0)
> 3744 {
> 3745 char *s = tgetstr ("me", address);
>
> At conditional (1): "s != 0" taking true path
>
> 3746 if (s != 0)
> 3747 tty->TS_end_standout_mode = s;
> 3748 else
> 3749 tty->TS_standout_mode = 0;
> 3750 }
> 3751
>
> At conditional (2): "(tty)->TF_teleray != 0" taking true path
>
> 3752 if (tty->TF_teleray)
> 3753 {
> 3754 tty->Wcm->cm_tab = 0;
> 3755 /* We can't support standout mode, because it uses magic
cookies. */
> 3756 tty->TS_standout_mode = 0;
> 3757 /* But that means we cannot rely on ^M to go to column
zero! */
> 3758 CR (tty) = 0;
> 3759 /* LF can't be trusted either -- can alter hpos */
> 3760 /* if move at column 0 thru a line with TS_standout_mode
*/
> 3761 Down (tty) = 0;
> 3762 }
> 3763
> 3764 /* Special handling for certain terminal types known to need
it */
> 3765
>
> At conditional (3): "strcmp == 0" taking true path
>
> 3766 if (!strcmp (terminal_type, "supdup"))
> 3767 {
> 3768 terminal->memory_below_frame = 1;
> 3769 tty->Wcm->cm_losewrap = 1;
> 3770 }
>
> At conditional (4): "strncmp == 0" taking false path
> At conditional (5): "strcmp == 0" taking false path
>
> 3771 if (!strncmp (terminal_type, "c10", 3)
> 3772 || !strcmp (terminal_type, "perq"))
> 3773 {
> 3774 /* Supply a makeshift :wi string.
> 3775 This string is not valid in general since it works only
> 3776 for windows starting at the upper left corner;
> 3777 but that is all Emacs uses.
> 3778
> 3779 This string works only if the frame is using
> 3780 the top of the video memory, because addressing is
memory-relative.
> 3781 So first check the :ti string to see if that is true.
> 3782
> 3783 It would be simpler if the :wi string could go in the
termcap
> 3784 entry, but it can't because it is not fully valid.
> 3785 If it were in the termcap entry, it would confuse
other programs. */
> 3786 if (!tty->TS_set_window)
> 3787 {
> 3788 p = tty->TS_termcap_modes;
> 3789 while (*p && strcmp (p, "\033v "))
> 3790 p++;
> 3791 if (*p)
> 3792 tty->TS_set_window = "\033v%C %C %C %C ";
> 3793 }
> 3794 /* Termcap entry often fails to have :in: flag */
> 3795 terminal->must_write_spaces = 1;
> 3796 /* :ti string typically fails to have \E^G! in it */
> 3797 /* This limits scope of insert-char to one line. */
> 3798 strcpy (area, tty->TS_termcap_modes);
> 3799 strcat (area, "\033\007!");
> 3800 tty->TS_termcap_modes = area;
> 3801 area += strlen (area) + 1;
> 3802 p = AbsPosition (tty);
> 3803 /* Change all %+ parameters to %C, to handle
> 3804 values above 96 correctly for the C100. */
> 3805 while (*p)
> 3806 {
> 3807 if (p[0] == '%' && p[1] == '+')
> 3808 p[1] = 'C';
> 3809 p++;
> 3810 }
> 3811 }
> 3812
> 3813 tty->specified_window = FrameRows (tty);
> 3814
>
> At conditional (6): "Wcm_init == -1" taking false path
>
> 3815 if (Wcm_init (tty) == -1) /* can't do cursor motion */
> 3816 {
> 3817 maybe_fatal (must_succeed, NULL, terminal,
> 3818 "Terminal type \"%s\" is not powerful enough
to run Emacs",
> 3819 # ifdef TERMINFO
> 3820 "Terminal type \"%s\" is not powerful enough
to run Emacs.\n\
> 3821 It lacks the ability to position the cursor.\n\
> 3822 If that is not the actual type of terminal you have,\n\
> 3823 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
> 3824 `setenv TERM ...') to specify the correct type. It may be
necessary\n\
> 3825 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
> 3826 # else /* TERMCAP */
> 3827 "Terminal type \"%s\" is not powerful enough
to run Emacs.\n\
> 3828 It lacks the ability to position the cursor.\n\
> 3829 If that is not the actual type of terminal you have,\n\
> 3830 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
> 3831 `setenv TERM ...') to specify the correct type. It may be
necessary\n\
> 3832 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
> 3833 # endif /* TERMINFO */
> 3834 terminal_type);
> 3835 }
> 3836
>
> At conditional (7): "((tty)->Wcm)->cm_rows <= 0" taking false path
> At conditional (8): "((tty)->Wcm)->cm_cols <= 0" taking false path
>
> 3837 if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0)
> 3838 maybe_fatal (must_succeed, NULL, terminal,
> 3839 "Could not determine the frame size",
> 3840 "Could not determine the frame size");
> 3841
>
> At conditional (9): "(tty)->TS_delete_mode != 0" taking true path
> At conditional (10): "(tty)->TS_insert_mode != 0" taking true path
> At conditional (11): "strcmp == 0" taking true path
>
> 3842 tty->delete_in_insert_mode
> 3843 = tty->TS_delete_mode && tty->TS_insert_mode
> 3844 && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode);
> 3845
>
> At conditional (12): "(tty)->TS_standout_mode != 0" taking false path
>
> 3846 tty->se_is_so = (tty->TS_standout_mode
> 3847 && tty->TS_end_standout_mode
> 3848 && !strcmp (tty->TS_standout_mode,
tty->TS_end_standout_mode));
> 3849
>
> At conditional (13): "tabs_safe_p != 0" taking true path
> At conditional (14): "((tty)->Wcm)->cm_tabwidth == 8" taking true path
>
> 3850 UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth
(tty) == 8;
> 3851
>
> At conditional (15): "((tty)->Wcm)->cm_abs != 0" taking true path
> At conditional (16): "(tty)->TS_set_window != 0" taking true path
>
> 3852 terminal->scroll_region_ok
> 3853 = (tty->Wcm->cm_abs
> 3854 && (tty->TS_set_window || tty->TS_set_scroll_region ||
tty->TS_set_scroll_region_1));
> 3855
>
> At conditional (17): "(tty)->TS_ins_line != 0" taking true path
> At conditional (18): "(tty)->TS_del_line != 0" taking true path
>
> 3856 terminal->line_ins_del_ok
> 3857 = (((tty->TS_ins_line || tty->TS_ins_multi_lines)
> 3858 && (tty->TS_del_line || tty->TS_del_multi_lines))
> 3859 || (terminal->scroll_region_ok
> 3860 && tty->TS_fwd_scroll && tty->TS_rev_scroll));
> 3861
>
> At conditional (19): "(tty)->TS_ins_char != 0" taking true path
> At conditional (20): "(tty)->TS_del_char != 0" taking true path
>
> 3862 terminal->char_ins_del_ok
> 3863 = ((tty->TS_ins_char || tty->TS_insert_mode
> 3864 || tty->TS_pad_inserted_char || tty->TS_ins_multi_chars)
> 3865 && (tty->TS_del_char || tty->TS_del_multi_chars));
> 3866
>
> At conditional (21): "(tty)->TS_clr_line != 0" taking true path
>
> 3867 terminal->fast_clear_end_of_line = tty->TS_clr_line != 0;
> 3868
> 3869 init_baud_rate (fileno (tty->input));
> 3870
> 3871 /* Don't do this. I think termcap may still need the buffer.
*/
> 3872 /* xfree (buffer); */
> 3873
> 3874 #endif /* not DOS_NT */
> 3875
> 3876 /* Init system terminal modes (RAW or CBREAK, etc.). */
> 3877 init_sys_modes (tty);
> 3878
>
> Event leaked_storage: Returned without freeing storage "area"
> Also see events: [alloc_fn][var_assign]
This looks like it's a problem, nothing keeps track of `area',
`delete_tty' does not free it, so this leaks 4KB per tty
creation/deletion, i.e. for each use of "emacsclient -t".