0

I have a c++ code that loads a python interepter which uses stderr:

intereptor.pyx
stderr_dup = os.fdopen(sys.stderr.fileno(), 'wb', 0)

The problem is that after Py_Finalize is called, stderr is closed and I can't use it in c++. should I just reopen it in c++ by

open(stderr)

Or I can prevent this behaviour from the python side (os.dup/dup2)? I tired replacing the above fdopen with:

stderr_dup = os.dup(sys.stderr.fileno())

But Py_Finalize still closes stderr.

Atheel Massalha
  • 424
  • 1
  • 6
  • 18
  • so its expected from it to close stderr? how should I open it back in c++? I need to save it before calling Py_Initilize? – Atheel Massalha May 10 '23 at 07:18
  • 1
    Can you dup stderr into an additional fd, and then set that fd as stderr once the Python stuff is finished? For example: `int stderr_copy = dup(stderr); ... Python ...; dup2(stderr_copy, stderr)`. – Jack Humphries May 10 '23 at 07:26
  • @JackHumphries that seems to work!, thanks! you can add it as an answoer if you like – Atheel Massalha May 10 '23 at 07:48

2 Answers2

1

You can solve this from the Python side far more easily:

stderr_dup = os.fdopen(sys.stderr.fileno(), 'wb', 0, closefd=False)

From the documentation:

If closefd is False and a file descriptor rather than a filename was given, the underlying file descriptor will be kept open when the file is closed.

Botje
  • 26,269
  • 3
  • 31
  • 41
  • looks promising, but Im surprized it didn't work. After Py_Finilize I have stderr="Bad file descriptor" – Atheel Massalha May 10 '23 at 09:02
  • Cannot reproduce that here. `fprintf(stderr, ...)` works just fine after calling `Py_Finalize`. Are you sure there's not something else closing stderr? – Botje May 10 '23 at 09:13
  • Im doing a dlclose on the python_lib, not sure if related. – Atheel Massalha May 10 '23 at 09:38
  • I suggest you whittle your program down to a [mre] that others can use to verify their suggestions. Very often the real problem is found during this process – Botje May 10 '23 at 09:47
  • I guess the python unload. – Atheel Massalha May 16 '23 at 09:48
  • If only there was a tool you could ask to stop the program when a certain function was called... Sounds like a better idea than guessing. – Botje May 16 '23 at 13:56
  • what function is called when python is unloaded? (not exit_handler, I mean real unload) – Atheel Massalha May 17 '23 at 05:14
  • Your statement is that python closes stderr "on unload", so I suggest you put a breakpoint on the close system call and see what actually closes stderr. – Botje May 17 '23 at 07:18
1

You could dup stderr into an additional file descriptor, and then set that file descriptor as stderr once the Python stuff is finished.

int stderr_copy = dup(stderr);
// ... Python ...
dup2(stderr_copy, stderr);
Jack Humphries
  • 13,056
  • 14
  • 84
  • 125