sdgfsdh sdgfsdh - 28 days ago 7
C++ Question

Use-after-delete in libuv app?

I am trying to use libuv to launch a process in a cross-platform way. To test the library, I have written a small C++ application that calls

sleep 1
and then exits. The problem is that sometimes (~5% of the time) it crashes with the following error from libuv:

EFAULT bad address in system call argument


Here is my code:

#include <iostream>
#include <string>
#include <memory>
#include <cstring>

#include <uv.h>

char* a;
char* b;

char** args;

std::string error_to_string(int const& error) {
return std::string(uv_err_name(error)) +
" " +
std::string(uv_strerror(error));
}

void on_exit(uv_process_t* req, int64_t exit_status, int term_signal) {
std::cout << "I'm back! " << std::endl;
std::cout << "exit_status " << exit_status
<< " term_signal " << term_signal << std::endl;

uv_close((uv_handle_t*)req, nullptr);
}

int main(int argc, const char** argv) {

auto* loop = new uv_loop_t();

uv_loop_init(loop);

auto* process = new uv_process_t();

uv_process_options_t options = {};

a = new char[100];
b = new char[100];

strcpy(a, "sleep\0");
strcpy(b, "1\0");

args = new char*[2];
args[0] = a;
args[1] = b;

options.exit_cb = on_exit;
options.file = "sleep";
options.args = args;

std::cout << "Going to sleep..." << std::endl;

int const r = uv_spawn(loop, process, &options);

if (r < 0) {
std::cout << error_to_string(r) << std::endl;
return 1;
}

uv_run(loop, UV_RUN_DEFAULT);

return 0;
}


I am using libuv 1.11.0, Clang 4.0.1 and C++ 14.

Can you spot my mistake?

Answer Source

Your args array is set up wrong. It should be:

args = new char*[3];
args[0] = a;
args[1] = b;
args[2] = NULL;

Otherwise uv_spawn doesn't know where the end of the array is.