一段很简单的C++代码, 输入a,b 输出a/b;
测试代码如下
/***
* @ _oo0oo_
* @ o8888888o
* @ 88" . "88
* @ (| -_- |)
* @ 0\ = /0
* @ ___/`---'\___
* @ .' \\| |// '.
* @ / \\||| : |||// \
* @ / _||||| -:- |||||- \
* @ | | \\\ - /// | |
* @ | \_| ''\---/'' |_/ |
* @ \ .-\__ '-' ___/-. /
* @ ___'. .' /--.--\ `. .'___
* @ ."" '< `.___\_<|>_/___.' >' "".
* @ | | : `- \`.;`\ _ /`;.`/ - ` : | |
* @ \ \ `_. \_ __\ /__ _/ .-` / /
* @ =====`-.____`.___ \_____/___.-`___.-'=====
* @ `=---='
* @
* @
* @ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* @
* @ 佛祖保佑 永不宕机 永无BUG
* @
* @
*/
# 2.cpp
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(int argc,char *argv[]){
int a,b;
int len = argc;
cout<<"argv[0] :"<<argv[0]<<endl;
cout<<"input a and b"<<endl;
cin>>a>>b;
cout<<"a : "<<a<<" b is "<<b<<endl;
cout<<"a/b is :"<<a/b<<endl;
return 0;
}
直接执行肯定是没问题的,
但是当我想fork一个子进程通过execv进行调用的时候, 会出现内存越界读的问题
如下错误:
root@0187031113b5:/work05# ./test.ccc
root@0187031113b5:/work05#
argv[0] :/work05/2.out
input a and b
a : -1422482224 b is 537128240
a/b is :-2
execve fork 的代码如下:
#test.cpp
#2.out 为上述a/b代码的可执行文件
int main(){
int chid = fork();
if(chid <0){
PFATAL("fork error");
}else if(!chid){
std::string tp = "<path to >/2.out";
char * a_argv[] = {strdup(tp.c_str()),nullptr};
char *envp[] = {};
execve(a_argv[0],a_argv,envp);
}
return 0;
}
当我尝试将a_argv[] 修改如下时
char * a_argv[] = {strdup(tp.c_str())};
execve未正确执行,如下图效果
解决方式
当我们想使用fork+execv以及stdin
时, 应该使用dup2
文件重定向函数,将输入in.txt
等文件内容作为` STDIN_FILEN
/* Standard file descriptors. */
#define STDIN_FILENO 0 /* Standard input. */
#define STDOUT_FILENO 1 /* Standard output. */
#define STDERR_FILENO 2 /* Standard error output. */
正确的方式如下代码所示:
int main(){
int status;
std::string fcur = "<path to input>/.cur_input";
int fd = open(fcur.c_str(),O_RDONLY);
int chid = fork();
if(chid <0){
PFATAL("fork error");
}else if(!chid){
/* Child */
std::string tp = "<path to >/2.out";
std::vector<std::string> vt;
vt.push_back(tp);
dup2(fd,STDIN_FILENO);
close(fd);
char * a_argv[] = {strdup(tp.c_str()),nullptr};
char *envp[] = {};
execv(a_argv[0],a_argv);
}
/* Parents*/
wait(&status);
close(fd);