c - C - stackdump,带有多个 fork+redirect+exec 的奇怪输出
问题描述
我有一个 C 程序(我们称之为“ progam1
”)以及 3 个输入文件(比如"in1.txt", "in2.txt", in3.txt"
)和 3 个初始为空的输出文件("out1, "out2","out3"
),它们表示对各种多边形的操作。
从progam1::main
,我调用fork 3次,在每个子进程中,我使用dup2
将标准输入/输出重定向到一个输入/输出文件,然后调用execve("helper",...),helper
另一个C程序在哪里它解析输入,进行一些计算并打印输出。
我似乎无法解决的问题是,每当我多次调用时execve(helper,...)
,第一次调用都可以正常工作(输入/输出如我所料),但随后出现问题;我似乎要么最终得到一个文件helper.exe.stackdump
,要么系统不断地将相同的数据打印到输出文件,或者其他一些意想不到的结果。
作为一个实验,我编写了另一个 C 程序 - "simpleWrite.c"
,它只是将输入复制到输出。我正在使用 cygwin 运行所有这些程序。
如果我传递
simpleWrite
给所有 3 个execve
调用program1
,那么一切正常(所有 3 个重定向的输入都按预期复制到 3 个输出文件)。如果我传递
simpleWrite
给一个孩子(比如第三个孩子)并./program1
从终端运行,那么系统完成并且第一个和第三个子进程按预期工作。第二个输出是空的,我最终"helper.exe.stackdump"
在我的目录中有一个文件。如果我只传递
helper
给所有 3 个孩子的 exec 并./program1
从终端运行,那么系统永远不会完成。当我检查输出文件时,一个输出如预期,一个输出为空,一个输出无限多次打印正确的数据。
谁能解释可能发生的事情!?或者解释什么是 stackdump 文件以及如何检查它,或者建议我如何解决这个问题?
这是我的代码的大致概念:
//program1.c
#define INPUT1 "in1.txt"
#definte OUTPUT1 "out1.txt"
// same for rest of input/output files
char* my_argv[2];
int main(int argc, char* argv[])
{
char prog_name[20] = "helper";
char prog_name2[20] = "simpleWrite";
my_argv[0] = "helper";
my_argv[1] = NULL;
pid_t pid1, pid2, pid3, pid;
int status;
if ((pid1 = fork()) < 0) {
printf("Failed to fork process 1\n");
exit(1);
}
else if (pid1 == 0)
{
// redirection here for the child only
int fd_in = open_file_desc(INPUT1);
int fd_out = open_file_desc(OUTPUT1);
dup2(fd_in, 0);
dup2(fd_out,1);
close(fd_in);
close(fd_out);
execve(prog_name, my_argv, NULL);
//alternately, execve(prog_name2, my_argv, NULL);
}
if ((pid2 = fork()) < 0) {
//...
}
else if (pid2 == 0)
{
int fd_in2 = open_file_desc(INPUT2);
int fd_out2 = open_file_desc(OUTPUT2);
...// same idea as above
}
// likewise for pid3
...
//back in parent process
pid = wait(&status);
printf("\n***Parent detects process %d was terminated ***\n", pid);
pid = wait(&status);
printf("\n*** Parent detects process %d was terminated ***\n", pid);
pid = wait(&status);
printf("\n*** Parent detects process %d was terminated ***\n", pid);
// dup2(sav_stdin, 0);
// dup2(sav_stdout, 1);
// dup2(sav_stderr, 2);
exit(0);
}
//helper.c
enum POLYGON { HEXAGON = 6, HEPTAGON = 7, OCTAGON = 8 };
struct point {
short *X, *Y;
};
struct polygon
{
enum POLYGON type;
struct point points;
};
struct Node {
struct polygon* poly;
struct Node* next;
};
struct Node *HEAD = NULL;
struct Node *TAIL = NULL;
int main()
{
int lastCommand = 0, polygonscreated =0, newPolygonBit;
//other variables needed for parsing/calculations
while (!lastCommand)
{
scanf("%llx", &input);
//parsing stuff
if (newPolygonBit == 1)
{
polygonscreated = polygonscreated+1;
scanf("%llx", &setOfPoints1);
scanf("%llx", &setOfPoints2);
struct polygon* polyptr = createPolygon(polyType, setOfPoints1, setOfPoints2);
func[ADD_POLYGON](polyptr);
}
lastCommand = input & 1;
}
freeList(HEAD);
printf("Created %d polygons", polygonscreated);
return polygonscreated;
}
//simpleWrite.c
int main()
{
char c;
while( read(0, &c, 1) > 0){
write(1, &c,1);
}
return 0;
}
解决方案
我对类似的代码有类似的问题。
我的问题是我希望我的子进程以特定的顺序执行。在这种情况下,假设您希望您的 3 个孩子按以下方式执行:-Child A -Child B -Child C
但是调度程序可能会以不同的顺序执行它们。让我们说ACB。
我希望这会有所帮助。
推荐阅读
- wordpress - 删除特定页面的 Jetpack 的 Open Graph 元标记
- c# - 在 DataGridView 中使用嵌套列表作为数据源的列表
- sql - Column' 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中
- erlang - elixir/erlang 中的 des-ecb 加密
- visual-studio-code - 在 Visual stuido 行中保存 html 文件时搞砸了
- javascript - 没有 async/await 就不会保存缓存中的更改
- hashcode - 为什么两个具有相似标签的 NodeList 不相等?
- blazor - 更新 Visual Studio 2019 预览后出错
- android - 即使在 postValue() Kotlin 之后 MutableLiveData ArrayList 也是空的
- scala - 在 VScode 中设置 Scala(metals) 时出现问题