This is the mail archive of the sid@sources.redhat.com mailing list for the SID project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: make trace_stream better preserve std::ofstream semantics


If the user redirects trace output to a file using something like:

    $ sid ... -e "set basic-0/cpu trace-filename trace.hello.basic"

then trace.hello.basic remains an empty file.

The problem is (I think) that basic_cpu::update_trace_destination
tries to close basic_cpu::trace_stream when it is already closed.

cpu_trace_stream is a subclass of std::ofstream, and does not override
its 'close' method.  According to ISO C++, std::ofstream::close sets
the stream's failbit if rdbuf ()->close fails (returns null).
std::basic_filebuf::close will return null if the filebuf is not open.

The first time basic_cpu::update_trace_destination gets called, cout_p
is true, and the base class's stream itself has never been opened.
The call to close sets the failbit, and subsequent output is ignored.

This patch overrides some more functions in cpu_trace_stream to make
their behavior better match that of its base class.  In particular,
the stream is treated as open if output is being directed to either
cout or the stream itself.

This doesn't completely reproduce the behavior of std::ofstream.  In
particular, it doesn't set failbit quite as often as it should, to be
completely consistent.


Rather than subclassing std::ofstream and doing this odd redirection
stuff, wouldn't it be simpler to just make trace_stream an instance of
plain old std::ofstream, and then call rdbuf () to set its streambuf
to either cout's streambuf, or a filebuf for the trace file?


sid/include/ChangeLog:
2004-01-13  Jim Blandy  <jimb@redhat.com>

	* sidcpuutil.h (sidutil::basic_cpu::cpu_trace_stream::is_open)
	(sidutil::basic_cpu::cpu_trace_stream::close): Override (non-virtual)
	definitions from std::ofstream, to better preserve std::ofstream's
	behavior, taking cout_p into account.

Index: sid/include/sidcpuutil.h
===================================================================
RCS file: /cvs/cvsfiles/devo/sid/include/sidcpuutil.h,v
retrieving revision 1.47.2.1
diff -c -r1.47.2.1 sidcpuutil.h
*** sid/include/sidcpuutil.h	22 Oct 2003 00:35:32 -0000	1.47.2.1
--- sid/include/sidcpuutil.h	14 Jan 2004 05:10:37 -0000
***************
*** 222,231 ****
--- 222,241 ----
  	:std::ofstream (filename.c_str ()), cout_p (false) {}
        void divert_to_file () { cout_p = false; }
        void divert_to_cout () { cout_p = true; }
+       bool is_open ()
+       {
+         return cout_p || std::ofstream::is_open ();
+       }
        void open (const std::string& filename)
        {
  	std::ofstream::open (filename.c_str (), std::ios::app);
  	cout_p = false;
+       }
+       void close ()
+       {
+         if (std::ofstream::is_open ())
+           std::ofstream::close ();
+         cout_p = false;
        }
        void end_line ()
        {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]