我在控制台应用程序中遇到一个奇怪的问题。
首先,代码片段:
的main.cpp
#include "DebugInterface.h"
static sigset_t signalSet;
static pthread_t CleanupHandlerThread;
DebugInterface* debugInterface = NULL;
void* CleanupHandler (void* param) {
int32_t sig, err;
err = sigwait (&signalSet, &sig);
delete debugInterface;
debugInterface = NULL;
exit (EXIT_SUCCESS);
return NULL;
}
int32_t main(int32_t argc, char** argv) {
sigemptyset (&signalSet);
sigaddset (&signalSet, SIGINT);
pthread_sigmask (SIG_BLOCK, &signalSet, NULL);
pthread_create (&CleanupHandlerThread, NULL, CleanupHandler, NULL);
debugInterface = new DebugInterface();
if (debugInterface != NULL) {
debugInterface->StartReading();
}
while (true) {
// Core functionality follows, but was commented out
// (was not relevant for problem, checked it -
// you may even remove this loop completely)
}
return EXIT_SUCCESS;
}
DebugInterface.h
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <iomanip>
#include <readline/readline.h>
#include <readline/history.h>
#include <signal.h>
class DebugInterface {
public:
DebugInterface() { }
virtual ~DebugInterface() { }
private:
pthread_t ConsoleHandlerThread;
private:
static void* ConsoleHandler (void* param);
public:
bool StartReading();
};
DebugInterface.cpp
#include "DebugInterface.h"
void* DebugInterface::ConsoleHandler (void* param) {
while (true) {
char* input = readline ("\n> ");
// Handle input, was commented out, too (irrelevant for problem)
free (input);
}
return NULL;
}
bool DebugInterface::StartReading() {
if (pthread_create (&ConsoleHandlerThread, NULL, DebugInterface::ConsoleHandler, NULL) != 0) {
return false;
}
return true;
}
代码运行正常并且符合预期,但是当它通过捕获信号SIGINT退出并终止时,控制台输出后来被隐藏(即控制台/终端的行为类似于应用命令“stty -echo”)。
我已经插入了代码'system(“stty echo”);'在退出之前的函数CleanupHandler中它“解决”了问题,但这不是正确的解决方案......也许我错过了一个没有出现的严重错误。我还没弄清楚我的代码在终止后如何影响控制台输出/终端本身,因为没有任何系统调用/函数调用可能会改变控制台行为(我只使用“printf”和颜色格式化控制台输出)。
上面的代码片段应该重现问题,编译器/链接器配置和输出是:
make all
Building file: ../main.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.d" -o"main.o" "../main.cpp"
Finished building: ../main.cpp
Building target: Testproject
Invoking: GCC C++ Linker
g++ -o"Testproject" ./DebugInterface.o ./main.o -lreadline -lpthread
Finished building target: Testproject
我正在服务器上进行远程开发,问题就是通过这种方式和SSH进行,所以这不是任何控制台错误。此外,将控制台输入处理程序放在主线程中并将子线程中的核心功能/循环放在一起并没有什么区别。
提前感谢您的帮助。
答案 0 :(得分:4)
接收信号时,您的程序没有完全终止。原因是readline库。
检查readline文档中有关信号处理的内容here
答案 1 :(得分:1)
运行strace
下的代码,您可能会发现终端输出的确切位置。
答案 2 :(得分:0)
谢谢,根据GNU Readline Library添加了两个清理函数解决了这个问题。
您必须在表达式“delete debugInterface;”之前添加以下函数:
rl_cleanup_after_signal();
rl_free_line_state();
[...]
delete debugInterface;