社区新版论坛已上线,点击立即前往!使用 openKylin 账户授权登录,解锁更多体验!

openKylin论坛

 找回密码

给Mate终端与GDB增加快捷键 [复制链接]

最近开始学习Linux编程,在Mate终端里试用了GDB的调试方式,对于习惯了用F5、F10和F11来调试的我来说,还真有点不习惯。于是我就把给Mate终端与GDB增加快捷键当作学习Linux编程的第一个实验目标来完成。现在我就把总结出来的方法分享给大家。
下载Mate终端源程序并解压缩:
里面有两个文件:
mate-terminal-1.21.0.tar.gz是原始源码包
mate-terminal-1.21.1.tar.xz是我改完的源码包
不想自己动手的的朋友可以下载我改过的包。编译安装方法在后面。
1.      添加菜单
1)      先将下面的菜单代码添加到src/terminal-window.c文件中的terminal_window_init函数,menu_entries数组,/* Terminal menu */段的前面。
/* Debugmenu */
   {
            "DebugProgram", NULL, N_("DebugProgram"), "F2",
            NULL,
            G_CALLBACK (debug_program_callback)
        },
   {
            "DebugProcess", NULL,N_("Debug Process"), "F3",
            NULL,
            G_CALLBACK (debug_process_callback)
        },
   {
            "DebugStart", NULL, N_("Debug Start"),"F4",
            NULL,
            G_CALLBACK (debug_start_callback)
        },
   {
            "DebugContinue", NULL,N_("Debug Continue"), "F5",
            NULL,
            G_CALLBACK (debug_continue_callback)
        },
   {
            "DebugNext", NULL, N_("Debug Next"),"F10",
            NULL,
            G_CALLBACK (debug_next_callback)
        },
   {
            "DebugStep", NULL, N_("Debug Step"),"F11",
            NULL,
            G_CALLBACK (debug_step_callback)
        },
再在/* Toplevel */段中的{ "Search", NULL, N_("_Search") },下面加入
{ "Debug", NULL, N_("Debug") },
2)      将下面的菜单项添加到src/terminal.xml文件中的<menuaction="Terminal">段的前面。
<menu action="Debug">
<menuitem action="DebugProgram" />
<menuitem action="DebugProcess" />
<separator />
<menuitem action="DebugStart" />
<menuitem action="DebugContinue" />
<menuitem action="DebugNext" />
<menuitem action="DebugStep" />
</menu>
3)      打开po/ zh_CN.po文件,查找src/terminal-window.c段,将下面的字段添加到里面。
msgid"Debug"
msgstr"调试"
msgid"Debug Program"
msgstr"调试程序"
msgid"Debug Process"
msgstr"调试进程"
msgid"Debug Start"
msgstr"开始调试"
msgid"Debug Continue"
msgstr"继续执行"
msgid"Debug Next"
msgstr"单步执行"
msgid"Debug Step"
msgstr"进入函数"
msgid"Program Name"
msgstr"程序名称"
msgid"Name:"
msgstr"名称:"
msgid"Process Id"
msgstr"进程ID"
2.      添加调用代码
1)      将下面代码添加到/src/terminal-window.c文件中的terminal_window_init (TerminalWindow *window)函数前面。
staticvoid
terminal_get_program_name_dialog_response_cb(GtkWidget *dialog,
                                       intresponse,
                                      TerminalScreen *screen)
{
    if (response == GTK_RESPONSE_OK)
    {
        GtkEntry *entry;
        const gchar *gtext;
            GString *gstr;
        entry = GTK_ENTRY (g_object_get_data(G_OBJECT (dialog), "name-entry"));
        gtext = gtk_entry_get_text (entry);
            gstr = g_string_new(NULL);
            gstr = g_string_assign(gstr,"gdb ");
            g_string_append(gstr, gtext);
            gstr = g_string_append_c(gstr,'\n');
            vte_terminal_feed_child(screen,gstr->str, gstr->len);
            g_string_free(gstr, TRUE);
    }
    gtk_widget_destroy (dialog);
}
staticvoid
terminal_get_program_id_dialog_response_cb(GtkWidget *dialog,
                                       int response,
                                      TerminalScreen *screen)
{
    if (response == GTK_RESPONSE_OK)
    {
        GtkEntry *entry;
        const gchar *gtext;
            GString *gstr;
        entry = GTK_ENTRY (g_object_get_data(G_OBJECT (dialog), "id-entry"));
        gtext = gtk_entry_get_text (entry);
            gstr = g_string_new(NULL);
            gstr = g_string_assign(gstr,"gdb --pid ");
            g_string_append(gstr, gtext);
            gstr = g_string_append_c(gstr,'\n');
            vte_terminal_feed_child(screen,gstr->str, gstr->len);
            g_string_free(gstr, TRUE);
    }
    gtk_widget_destroy (dialog);
}
staticvoid
debug_program_callback(GtkAction *action,TerminalWindow *window)
{
   TerminalWindowPrivate *priv =window->priv;
   GtkWidget *dialog, *message_area, *hbox,*label, *entry;
   if (priv->active_screen == NULL)
            return;
   dialog = gtk_message_dialog_new (GTK_WINDOW(window),
                     GTK_DIALOG_MODAL |GTK_DIALOG_DESTROY_WITH_PARENT,
                     GTK_MESSAGE_OTHER,
                     GTK_BUTTONS_OK_CANCEL,
                     "%s","");
   gtk_window_set_title (GTK_WINDOW (dialog),_("Program Name"));
   gtk_window_set_resizable (GTK_WINDOW(dialog), FALSE);
   gtk_window_set_role (GTK_WINDOW (dialog),"Program Name");
   gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_OK);
   g_signal_connect (dialog,"response",
                     G_CALLBACK(terminal_get_program_name_dialog_response_cb),
                     priv->active_screen);
   g_signal_connect (dialog,"delete-event",
                     G_CALLBACK(terminal_util_dialog_response_on_delete), NULL);
   message_area =gtk_message_dialog_get_message_area
                     (GTK_MESSAGE_DIALOG(dialog));
   gtk_container_foreach (
                     GTK_CONTAINER(message_area),
                     (GtkCallback)gtk_widget_hide,
                     NULL);
   hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
   gtk_box_pack_start (GTK_BOX (message_area),hbox, FALSE, FALSE, 0);
   label = gtk_label_new_with_mnemonic(_("Name:"));
   gtk_label_set_xalign (GTK_LABEL (label),0.0);
   gtk_label_set_yalign (GTK_LABEL (label),0.5);
   gtk_box_pack_start (GTK_BOX (hbox), label,FALSE, FALSE, 0);
   entry = gtk_entry_new ();
   gtk_entry_set_width_chars (GTK_ENTRY (entry),32);
   gtk_entry_set_activates_default (GTK_ENTRY(entry), TRUE);
   gtk_label_set_mnemonic_widget (GTK_LABEL(label), entry);
   gtk_box_pack_start (GTK_BOX (hbox), entry,TRUE, TRUE, 0);
   gtk_widget_show_all (hbox);
   gtk_widget_grab_focus (entry);
    g_object_set_data (G_OBJECT (dialog),"name-entry", entry);
   gtk_window_present (GTK_WINDOW (dialog));
}
staticvoid
debug_process_callback(GtkAction *action,TerminalWindow *window)
{
   TerminalWindowPrivate *priv =window->priv;
   GtkWidget *dialog, *message_area, *hbox,*label, *entry;
   if (priv->active_screen == NULL)
            return;
   dialog = gtk_message_dialog_new (GTK_WINDOW(window),
                     GTK_DIALOG_MODAL |GTK_DIALOG_DESTROY_WITH_PARENT,
                     GTK_MESSAGE_OTHER,
                     GTK_BUTTONS_OK_CANCEL,
                     "%s","");
   gtk_window_set_title (GTK_WINDOW (dialog),_("Process Id"));
   gtk_window_set_resizable (GTK_WINDOW(dialog), FALSE);
   gtk_window_set_role (GTK_WINDOW (dialog),"mate-terminal-change-title");
   gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_OK);
   g_signal_connect (dialog,"response",
                     G_CALLBACK(terminal_get_program_id_dialog_response_cb),
                     priv->active_screen);
   g_signal_connect (dialog,"delete-event",
                     G_CALLBACK(terminal_util_dialog_response_on_delete), NULL);
   message_area =gtk_message_dialog_get_message_area
                     (GTK_MESSAGE_DIALOG(dialog));
   gtk_container_foreach (
                     GTK_CONTAINER(message_area),
                     (GtkCallback)gtk_widget_hide,
                     NULL);
   hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12);
   gtk_box_pack_start (GTK_BOX (message_area),hbox, FALSE, FALSE, 0);
   label = gtk_label_new_with_mnemonic(_("ID:"));
   gtk_label_set_xalign (GTK_LABEL (label),0.0);
   gtk_label_set_yalign (GTK_LABEL (label),0.5);
   gtk_box_pack_start (GTK_BOX (hbox), label,FALSE, FALSE, 0);
   entry = gtk_entry_new ();
   gtk_entry_set_width_chars (GTK_ENTRY (entry),32);
   gtk_entry_set_activates_default (GTK_ENTRY(entry), TRUE);
   gtk_label_set_mnemonic_widget (GTK_LABEL(label), entry);
   gtk_box_pack_start (GTK_BOX (hbox), entry,TRUE, TRUE, 0);
   gtk_widget_show_all (hbox);
   gtk_widget_grab_focus (entry);
    g_object_set_data (G_OBJECT (dialog),"id-entry", entry);
   gtk_window_present (GTK_WINDOW (dialog));
}
staticvoid
debug_start_callback(GtkAction *action,TerminalWindow *window)
{
   GString *gstr;
   gstr = g_string_new(NULL);
   gstr = g_string_assign(gstr,"start\n");
   vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
   g_string_free(gstr, TRUE);
}
staticvoid
debug_continue_callback(GtkAction *action,TerminalWindow *window)
{
   GString *gstr;
   gstr = g_string_new(NULL);
   gstr = g_string_assign(gstr,"c\n");
   vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
   g_string_free(gstr, TRUE);
}
staticvoid
debug_next_callback(GtkAction *action,TerminalWindow *window)
{
   GString *gstr;
   gstr = g_string_new(NULL);
   gstr = g_string_assign(gstr,"n\n");
   vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
   g_string_free(gstr, TRUE);
}
staticvoid
debug_step_callback(GtkAction *action,TerminalWindow *window)
{
   GString *gstr;
   gstr = g_string_new(NULL);
   gstr = g_string_assign(gstr,"s\n");
   vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
   g_string_free(gstr, TRUE);
}
2)      本来这样就应该可以了,但试用发现F5、F10和F11这三个键与Mate终端的按键有冲突,不得不加入代码屏蔽掉原有的快捷键。代码如下,将它们添加到window_key_press_cb函数returnFALSE;语句之前。
elseif(event->keyval == GDK_KEY_F5)
   {
            TerminalWindow *window =TERMINAL_WINDOW (widget);
            GString *gstr;
            gstr = g_string_new(NULL);
            gstr = g_string_assign(gstr,"c\n");
            vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
            g_string_free(gstr, TRUE);
            return TRUE;
   }
   else if(event->keyval == GDK_KEY_F10)
   {
            TerminalWindow *window =TERMINAL_WINDOW (widget);
            GString *gstr;
            gstr = g_string_new(NULL);
            gstr = g_string_assign(gstr,"n\n");
            vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
            g_string_free(gstr, TRUE);
            return TRUE;
   }
   else if(event->keyval == GDK_KEY_F11)
   {
            TerminalWindow *window =TERMINAL_WINDOW (widget);
            GString *gstr;
            gstr = g_string_new(NULL);
            gstr = g_string_assign(gstr,"s\n");
            vte_terminal_feed_child(VTE_TERMINAL(window->priv->active_screen), gstr->str, gstr->len);
            g_string_free(gstr, TRUE);
            return TRUE;
}
编译安装
本例是在ubuntukylin-18.04-enhanced-amd64系统下进行的,如果你没有安装过mate-commonyelp-tools执行下面命令安装它们。
sudoapt-get install mate-common
sudoapt-get install yelp-tools
         注意命令执行完后是否有错误提示,如果有重新执行它们即可解决。
         安装依赖库,执行:
    sudo apt-get install libglib2.0-dev
sudo apt-get installlibvte-2.91-dev
sudo apt-get installlibdconf-dev
安装Mate终端,执行:
./autogen.sh
make
sudomake install
         安装完成。
添加好的菜单界面如下图:


gdb1.png (43.32 KB, 下载次数: 12)

gdb1.png
楼主
发表于 2018-8-16 14:17:37
回复

使用道具 举报

给Mate终端与GDB增加快捷键 [复制链接]

使用方法
         调试程序:
         按F2键弹出程序名称对话框, 在对话框里面填写要调试的程序名称,也可以包含路径,例如:
         Test
         ./ Test
         /home/用户名/ mate-terminal-1.21.1/src/ Test
         然后点确定即可进入调试了。先按F4开始调试,按F10一行一行的执行程序,如果该行是函数并且系统里面有该函数的源码,按F11即可进入该函数,按F5可以全速运行程序。

调试进程
         当一些程序运行起来后会关闭父进程,这时候就需要进程调试了,先在终端中输入ps –d查看要调试的进程ID,然后输入su进入root用户,(如果你是第一次使用su命令,先需要更改root用户密码,命令为sudo passwd root)按F3弹出进程ID对话框,在里面输入需要调试的进程ID,点确定进入调试,然后下断点程序就会停下来,这时我们就可以调试子程序了,方法与调试程序相同。

         本次分享到此结束。好了,朋友们再见了。
沙发
 楼主| 发表于 2018-8-16 14:25:23
回复

使用道具 举报

openKylin

GMT+8, 2024-6-15 19:06 , Processed in 0.019211 second(s), 20 queries , Gzip On.

Copyright ©2022 openKylin. All Rights Reserved .

ICP No. 15002470-12 Tianjin

快速回复 返回顶部 返回列表