Linux under gdb attach using (debugging process is already running)

On Linux, the implementation of a program multiple threads, when the program exits to perform operations sometimes encounter stuck phenomenon, if multi-module program, the code is large, it is difficult to quickly locate, then you can try the gdb attach method.

Main.cpp test code as follows, in order to make this program produces stuck phenomenon exit, in the first 51 rows push the thread sleep 100 Minutes:

#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());
		std::this_thread::sleep_for(std::chrono::seconds(1));
	}
}

} // namespace

int main()
{
	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 script reads as follows:

g++ -g -std=c++11 -o main main.cpp -lpthread
./main

Execution: $ ./build.sh, execution results are as follows, the program can not exit properly, resulting in stuck phenomenon:

Command: $ ps -aux | grep main, acquisition process (pid) of the main execution, as shown below, the process of implementation of main 18786:

Start gdb attach, execute gdb attach pid to debug a running program, execute: $ gdb attach 18786, if executed gdb attach when prompted: "ptrace: Operation not permitted", execute: $ sudo gdb attach 18786, the following figure shows:

Also perform: $ gdb main 18786, 18786 and gdb attach the same.

Commonly used commands are as follows:

1. bt: View all the call stack function, when abnormal program execution, you can see the call process procedure by this command;

2. info threads: Displays the current threads in the process;

3. thread id: switching to a specific thread id, typically after switching to the details thread bt perform other operations.

First execution info threads, found a total of three threads, the current thread id is 1, that is the main thread execution bt, will find a program card on the 77th line, that th1.join () statement that there is no quit in the push function; execution thread 2, and then executed bt, found pop functions performed in this thread, the card 24 in the first row on cv_.wait (LCK) statements; execution thread 3, and then performs bt, found in the implementation of this thread push function, the card the line 51 std :: this_thread :: sleep_for (std :: chrono :: minutes (100)); a statement analysis is completed, the program to understand the causes of stuck execution result as shown below:

GitHubhttps://github.com/fengbingchun/Messy_Test

Published 718 original articles · won praise 1131 · Views 6.09 million +

Guess you like

Origin blog.csdn.net/fengbingchun/article/details/99417062