pythoncsegmentation-faultembedding

Segmentation fault when executing a Python script in a C program?


I need to execute some python and C at the same time. I tried using Python.h:

#include <Python.h>

int python_program(char* cwd)
{  
  char* python_file_path;
  FILE* fd;
  int run;

  python_file_path = malloc(sizeof(char) * (strlen(cwd) + strlen("src/query.py") + 1));
  strcpy(python_file_path, cwd);
  strcat(python_file_path, "src/query.py");
  fd = fopen(python_file_path, "r");

  Py_Initialize(); 


  run = PyRun_AnyFile(fd, "query.py"); //this part is where the bug occur i think

  Py_Finalize();

  free(python_file_path);
}

int main(int argc, char *argv[])
{
  char cwd_buffer[64];
  

  getcwd(cwd_buffer, sizeof(cwd_buffer));
  python_program(cwd_buffer);
  
  return 0;
}

...but there's an error with segmentation fault.

26057 segmentation fault (core dumped)  ../spotify-viewer-cli

I isolated the Python.h part and it's the problem. So how can I execute the python file in my C program?


Solution

  • Golden rule: error handling is not an option but a hard requirement in programming (pointed out by answers and comments).

    Failing to include it might work for a while, but almost certainly will come back and bite in the ass at a later time, and it will do it so hard that someone (unfortunately, often not the same person who wrote the faulty code) will spend much more time (than writing it in the 1st place) fixing subtle errors (or crashes).

    Also, reading the documentation for the used functions, might save precious time too, avoiding all kinds of errors generated by passing to them arguments based on some false assumptions.

    Same case here (Undefined Behavior):

    I created a MCVE ([SO]: How to create a Minimal, Reproducible Example (reprex (mcve))), and also added some printf statements useful to identify the culprit (the preferred option would be to go step by step using a debugger (e.g.: [SourceWare]: GDB: The GNU Project Debugger)).

    Output:

    [cfati@cfati-5510-0:/mnt/e/Work/Dev/StackExchange/StackOverflow/q079208182]> ~/sopr.sh
    ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###
    
    [064bit prompt]> tree
    .
    +-- dir00
    ¦   +-- code00.py
    +-- main00.c
    
    1 directory, 2 files
    [064bit prompt]>
    [064bit prompt]> PY_VER="3.11"
    [064bit prompt]> gcc -fPIC -I/usr/include/python${PY_VER}  -o test${PY_VER} -L/usr/lib/$(uname -m)-linux-gnu main00.c -lpython${PY_VER}
    [064bit prompt]> ls
    dir00  main00.c  test3.11
    [064bit prompt]>
    [064bit prompt]> ./test${PY_VER}
    cwd (check its end): /mnt/e/Work/Dev/StackExchange/StackOverflow/q079208182
    script path: /mnt/e/Work/Dev/StackExchange/StackOverflow/q079208182/dir00/code00.py
    Python 3.11.3 (main, Apr  5 2023, 14:15:06) [GCC 9.4.0] 064bit on linux
    
    From Python - file: /mnt/e/Work/Dev/StackExchange/StackOverflow/q079208182/code00.py
    Script ran fine
    
    Done.