Linux下gdbattach的使⽤(调试已在运⾏的进程)在Linux上,执⾏有多线程的程序时,当程序执⾏退出操作时有时会遇到卡死现象,如果程序模块多,代码量⼤,很难快速定位,此时可试试gdb attach⽅法。
测试代码main.cpp如下,这⾥为了使程序退出时产⽣卡死现象,在第51⾏时push线程sleep 100分钟:
#include <stdio.h>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <chrono>
namespace {
class Queue {
public:
Queue() = default;
~Queue() { }
void Init(int num) {
for (int i = 0; i < num; ++i) {
queue_.push(i);
}
}
int Pop() {
std::unique_lock<std::mutex> lck(mutex_);
while (queue_.size() == 0) {
cv_.wait(lck);
}
int value = queue_.front();
queue_.pop();
return value;
}
void Push(int value) {
std::unique_lock<std::mutex> lck(mutex_);
queue_.push(value);
cv_.notify_all();
}
private:
std::queue<int> queue_;
std::mutex mutex_;
std::condition_variable cv_;
}; // class Queue
bool running = false;
void push(Queue& q) {
int value = 100;
while (running) {
q.Push(value++);
std::this_thread::sleep_for(std::chrono::minutes(100));
}
}
void pop(Queue& q) {
while (running) {
fprintf(stdout, "pop value: %d\n", q.Pop());
fprintf(stdout, "pop value: %d\n", q.Pop());
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
} // namespace
int main()linux下的sleep函数
{
fprintf(stdout, "test start\n");
Queue q;
q.Init(2);
running = true;
std::thread th1(push, std::ref(q));
std::thread th2(pop, std::ref(q));
std::this_thread::sleep_for(std::chrono::seconds(10));
running = false;
th1.join();
th2.join();
fprintf(stdout, "test end\n");
return 0;
}
build.sh脚本内容如下:
g++ -g -std=c++11 -o main main.cpp -lpthread
./main
执⾏:$ ./build.sh ,执⾏结果如下,程序⽆法正常退出,产⽣卡死现象:
通过命令:$ ps -aux | grep main ,获取执⾏main的进程(pid),如下图所⽰,执⾏main的进程为18786:
启动gdb attach,执⾏gdb attach pid即可调试正在运⾏的程序,执⾏:$ gdb attach 18786,若执⾏gdb attach时提⽰:”ptrace: Operation not permitted”,则执⾏:$ sudo gdb attach 18786,如下图所⽰:
也可执⾏:$ gdb main 18786,与gdb attach 18786相同。
常⽤的命令如下:
1. bt:查看函数调⽤栈的所有信息,当程序执⾏异常时,可通过此命令查看程序的调⽤过程;
2. info threads:显⽰当前进程中的线程;
3. thread id:切换到具体的线程id,⼀般切换到具体的线程后再执⾏bt等操作。
⾸先执⾏info threads,发现共有3个线程,当前线程id是1,即主线程,执⾏bt,会发现程序卡在第77⾏,即th1.join()语句上,即在push函数内没有退出;执⾏thread 2,再执⾏bt,发现此线程在执⾏pop函数,卡在了第24⾏的cv_.wait(lck)语句上;执⾏thread 3,再执⾏bt,发现此线程在执⾏push函数,卡在了第51⾏的std::this_thread::sleep_for(std::chrono::minutes(100));语句上,分析完成,了解了程序卡死的原因,执⾏结果如下图所⽰:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论