Skip to content

File descriptor leak in C-API #1388

Description

@chemsh

Describe the bug

In src/api/environment.f90, the releaseOutput_api subroutine (bound as xtb_releaseOutput) has a logic error that prevents file units from being closed. This causes a file descriptor leak when the C-API is used repeatedly (e.g., in geometry optimisation or MD), eventually hitting the OS limit with "Too many open files".

On line 203 (commit fc512bb):

  if (.not.any(env%ptr%unit /= [-1, stdout, stderr])) then
     close(unit=env%ptr%unit, iostat=stat, iomsg=message)

the condition is always .false. by defining not any of -1, stdout, or stderr, therefore close is never triggered.

To Reproduce

Here is a minimal example:

#include "xtb.h"
#include <stdio.h>
void main() {
    for (int i = 0; i < 1200; i++) {
        xtb_TEnvironment env = xtb_newEnvironment();
        char filename[255];
        snprintf(filename, sizeof(filename), "xtb_step_%d.log", i);
        xtb_setOutput(env, filename);
        // ... run calculation ...
        xtb_delEnvironment(&env);  // within this the file unit isn't closed as expected
        printf("### Step %d completed\n", i);
    }
}

This will crash at around step ~1000 (depending on ulimit -n) with an error opening a new file.

Expected behaviour

xtb_delEnvironment which calls releaseOutput_api should close file units that are not -1, stdout, or stderr. It can be easily fixed by changing /= to ==:

if (.not.any(env%ptr%unit == [-1, stdout, stderr])) then

Additional context

The bug was introduced in commit 37ae399 (C-API version 6.3, #222) in May 2020.

Thank you very much.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-APIConcerns the ISO-C layerunconfirmedThis report has not yet been confirmed by the developers

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions