es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo obtener más información de depuración para C++ std::ofstream al escribir en un dispositivo?

Buen día, estoy tratando de depurar este código C++ que interactúa con el dispositivo XDMA:

#include <fstream>
#include <iostream>
#include <unistd.h>

int main()
{
    std::ofstream output_;
    const char* output_name = "/dev/xdma/card0/h2c0";

    output_.exceptions(std::ios::failbit | std::ios::badbit);
    output_.rdbuf()->pubsetbuf(nullptr, 0);
    output_.open(output_name, std::ios::binary | std::ios::out);

    std::streamoff offset = 0x1e00000;
    output_.seekp(offset, std::ios::beg);

    const char buf[1] = "";
    std::streamsize size = 1;
    auto pos = output_.tellp();

    output_.write(buf, size); // <--- ERROR DE IOSTREAM

    output_.seekp(pos + size, std::ios::beg);
    return 0;
}

Sin embargo, este programa falla en la línea output_.write(buf, size); con un mensaje de error bastante vago:

terminate called after throwing an instance of 'std::_ios_failure'
  what():  basic_ios::clear: iostream error
Aborted (core dumped)

Y, si envuelvo output_.write(buf, size); en un bloque try & catch:

try {
    output.write(buf, size);
}
catch (std::system_error& e) {
    std::cerr << e.code().message() << "(" << e.code().value() << ")\n";
    return 1;
}

cambia a error de iostream(1). Esto no indica una razón de falla… Sé con certeza que puedo escribir en la dirección 0x1e00000, porque el código C alternativo está funcionando perfectamente. Así que el error está en el código o en la biblioteca de C++. ¿Cómo puedo obtener más información de depuración?</unistd.h>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para obtener más información de depuración, puede agregar la siguiente línea antes de la llamada a output_.write(buf, size):

    output_.exceptions(output_.exceptions() | std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
    

    Esto habilitará que las banderas del eofbit del flujo estén configuradas si se alcanza el final del flujo y la bandera del badbit si ocurre un error fatal, además de la bandera del failbit existente, que indica un error no fatal.

    Luego, puede volver a intentar capturar la excepción e imprimir el mensaje de error:

    try {
        output_.exceptions(output_.exceptions() | std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
        output_.write(buf, size);
    }
    catch (const std::ios_base::failure& e) {
        std::cerr << "Se produjo un error de E/S: " << e.what() << '\n';
        if (e.code() == std::make_error_code(std::io_errc::stream)) {
            std::cerr << "error de flujo: " << e.code().message() << " (" << e.code().value() << ")\n";
        }
        return 1;
    }
    

    Esto imprimirá el mensaje de error devuelto por e.what(), que ahora debería ser más útil. Además, si el error se debe a un error de flujo, el bloque de error de flujo imprimirá un mensaje de error más específico.

Comments are closed.