execve 执行遇到的问题-已解决

一段很简单的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未正确执行,如下图效果

image-20220713202128254

解决方式

当我们想使用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);

image-20220713222100498

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值