linux · 2021年 2月 25日 0

gcc

cgdb

linux上对C++进行调试,可以安装了CGDB

“cgdb可以看作gdb的界面增强版,用来替代gdb的 gdb -tui。cgdb主要功能是在调试时进行代码的同步显示,这无疑增加了调试的方便性,提高了调试效率。界面类似vi,符合unix/Linux下开发人员习惯,所以如果熟悉gdb和vi,几乎可以立即使用cgdb。”

安装

sudo apt install cgdb

CGDB使用

生产可调试文件

g++ -o a.out a.cpp -g

启用cgdb

cgdb a.out 

可以看到启动后,一共分出了三块窗口,分别是代码窗口,状态窗口,GDB窗口。

代码窗口

显示被源代码,自动标记出程序运行到的位置。当焦点在代码窗口时,可以浏览代码、查找代码以及执行命令 ,操作方式同vi 。当您处于代码窗口时,您已经处于CGDB模式中。常用命令如下:

i :   切换到GDB窗口 。
o :   打开文件选择框,可选择要显示的代码文件 。
空格 : 设置/取消断点 。
k/ up arrow:    向上移动一列
j/down arrow:   向下移动一列
h/left arrow:   向左移动一列
l/right arrow:  向右移动一列
gg:   移动到文件顶部
G:    移动到文件底部
/:    查找
F5:   发送一个run命令至GDB
F6:   发送一个continue命令至GDB
F7:   发送一个finish命令至GDB
F8:   发送一个next命令至GDB
F10:  发送一个step命令至GDB 

状态窗口

显示当前打开的源文件名,当代码窗口进入命令状态时,显示输入的命令等信息

GDB窗口

GDB的操作界面,同GDB 。

(gdb)help(简写h):查看命令帮助,具体命令查询在gdb中输入help + 命令

(gdb)run(简写r):重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件)

(gdb)start:单步执行,运行程序,停在第一执行语句

(gdb)list(简写l):查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数)

(gdb)set:设置变量的值

(gdb)next(简写n):单步调试(逐过程,函数直接执行)

(gdb)step(简写s):单步调试(逐语句:跳入自定义函数内部执行)

(gdb)backtrace(简写bt):查看函数的调用的栈帧和层级关系

(gdb)frame(简写f):切换函数的栈帧

(gdb)info(简写i):查看函数内部局部变量的数值

(gdb)finish:结束当前函数,返回到函数调用点

(gdb)continue(简写c):继续运行

(gdb)print(简写p):打印值及地址

(gdb)quit(简写q):退出gdb



(gdb)break+num(简写b n):在第num行设置断点,

(gdb)info breakpoints:查看当前设置的所有断点

(gdb)delete breakpoints_num(简写d n):删除第num个断点,

(gdb)display:追踪查看具体变量值

(gdb)undisplay:取消追踪观察变量

(gdb)watch:被设置观察点的变量发生修改时,打印显示

(gdb)i watch:显示观察点

(gdb)enable breakpoints:启用断点

(gdb)disable breakpoints:禁用断点

(gdb)x:查看内存x/20xw 显示20个单元,16进制,4字节每单元

(gdb)run argv[1] argv[2]:调试时命令行传参

(gdb)set follow-fork-mode child#Makefile项目管理:选择跟踪父子进程(fork())

core文件:先用$ ulimit -c 1024 开启core,当程序出错会自动生成core文件。调试时 gdb a core


ESC:         切换到代码窗口 。
quit/q:      退出cgdb
k/kill:   向GDB发送一个kill命令
set args []:   设置参数
show args:     显示参数
until:         当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体。
until [line_number]: 运行至某行,不仅仅用来跳出循环
call 函数(参数):    调用程序中可见的函数,并传递“参数”,如:call gdb_test(55)

参考文献:ran337287,CGDB中文使用手册,CGDB Manual

gdb

参考文献:linux命令大全gdb,gdb初级,gdb丰富c编程

gcc版本控制

cd Downloda/gcc46
sudo dpkg -i *.deb
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4 50
sudo update-alternatives --config gcc
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4 50
sudo update-alternatives --remove gcc /usr/bin/gcc-4.5
sudo apt-get install gcc-4.5 gcc-4.5-multilib g++-4.5 g++-4.5-multilib

g++编译后中文显示乱码

运行环境 Ubuntu20.04

g++版本 9.3.0

$ g++ --version
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.

测试代码

//4_2.cpp
#include <iostream>
using namespace std;
class Point    //Point 类的声明
{
public:    //外部接口
    Point(int xx=0, int yy=0) {X=xx;Y=yy;}  //构造函数
    Point(Point &p);    //拷贝构造函数
    int GetX() {return X;}
    int GetY() {return Y;}
private:    //私有数据
    int X,Y;
};
//成员函数的实现
Point::Point(Point &p)
{
    X=p.X;
    Y=p.Y;
    cout<<"拷贝构造函数被调用"<<endl;
}
//形参为Point类对象的函数
void fun1(Point p)
{    cout<<p.GetX()<<endl;
}
//返回值为Point类对象的函数
Point fun2()
{
    Point A(1,2);
    return A;
}
//主程序
int main()
{
    Point A(4,5);   //第一个对象A
    Point B(A);                  //情况一,用A初始化B。第一次调用拷贝构造函数
    cout<<B.GetX()<<endl;
    fun1(B);  //情况二,对象B作为fun1的实参。第二次调用拷贝构造函数
    B=fun2();  //情况三,函数的返回值是类对象,函数返回时,调用拷贝构造函数
    cout<<B.GetX()<<endl;
}

原始运行

$ g++ 4_2.cpp && ./a.out

4
4
1

解决方法

$ g++ -finput-charset='GBK' 4_2.cpp -o b && ./b

拷贝构造函数被调用
4
拷贝构造函数被调用
4
1

参考文献:luozhuang

gcc编译为windows exe文件

方法:
使用: mingw-w64-gcc
安装: sudo pacman -S mingw-w64-gcc
栗子:x86_64-w64-mingw32-gcc -fexec-charset=GBK sum1n.c -o sum1n.exe -static

exe 文件添加图标

  • 准备一个 myicon.icon 文件
  • 制作 myicon.rc 文件
  myicon ICON myicon.icon
  • 制作 myicon.o 文件
    x86_64-w64-mingw32-windres myicon.rc -o myicon.o
  • 生成带图标的 exe 可执行文件
    x86_64-w64-mingw32-gcc -fexec-charset=GBK sum1n.c myicon.o -o sum1n.exe
    img
TOC