diff -Naur ddrescue-1.17-rc4.orig/debug_print.cc ddrescue-1.17-rc4/debug_print.cc
--- ddrescue-1.17-rc4.orig/debug_print.cc 1970-01-01 07:00:00.000000000 +0700
+++ ddrescue-1.17-rc4/debug_print.cc 2013-06-29 21:20:31.604099000 +0700
@@ -0,0 +1,73 @@
+/***
+ * Debug printf library for C++
+ *
+ * Author: Alexander Sashnov
+ * License: Boost Software License
+ */
+#include
+#include
+#include
+#include
+#include
+
+#include "debug_print.h"
+
+
+int DebugFuncEntry::level = 0;
+
+static const int LOG_LINES_MAXIMUM = 10000;
+
+void debug_printf(const char *fmt, ...)
+{
+ va_list args;
+
+ static char *debug_log_filename = getenv("DEBUG_OUTPUT_FILENAME");
+ static FILE *fp = NULL;
+ static int n = 0;
+ static bool failed = false;
+ static time_t start_time = time(NULL);
+
+ if (! debug_log_filename)
+ return;
+
+ if (failed || n > LOG_LINES_MAXIMUM)
+ return;
+
+ if (!fp) {
+ fp = fopen(debug_log_filename, "w");
+ if (!fp) {
+ fprintf(stderr, "Unable to create %s: %s\n", debug_log_filename, strerror(errno));
+ failed = true;
+ return;
+ }
+ setbuf(fp, NULL);
+
+ fprintf(fp, "This is output from calls of 'debug_printf' function.\n"
+ "Every time the programm starts it creates new file (output for previous run will be lost)\n"
+ "\n"
+ " \n\n");
+ }
+
+ time_t cur_time = time(NULL);
+
+ double diff = difftime(cur_time, start_time);
+
+ (void) fprintf (fp, "%5.0f Debug: ", diff);
+ va_start (args, fmt);
+ (void) vfprintf (fp, fmt, args);
+ va_end (args);
+
+ // Put EOL char if it is not into the format string
+ int i = strlen(fmt);
+ if (i > 0 && fmt[i-1] != '\n')
+ fprintf(fp, "\n");
+
+ // Hint: you can set debugger's breakpoint here:
+ if (n == 15) {
+ ;
+ }
+
+ if (n++ == LOG_LINES_MAXIMUM) {
+ fprintf(fp, "That's it: maximum number of lines allowed for logging was reached.");
+ }
+}
diff -Naur ddrescue-1.17-rc4.orig/debug_print.h ddrescue-1.17-rc4/debug_print.h
--- ddrescue-1.17-rc4.orig/debug_print.h 1970-01-01 07:00:00.000000000 +0700
+++ ddrescue-1.17-rc4/debug_print.h 2013-06-29 21:18:18.624102000 +0700
@@ -0,0 +1,119 @@
+/***
+ * Debug printf library for C++
+ *
+ * Author: Alexander Sashnov
+ * License: Boost Software License
+ */
+#include
+#include
+
+/*
+ * For using debug log just start your programm with
+ * DEBUG_OUTPUT_FILENAME environment variable with
+ * filename to create.
+ *
+ *
+ * Example for using the following macros:
+ *
+ * void f(int n)
+ * {
+ * DEBUG_FUNC_ENTRY
+ *
+ * ...
+ *
+ * if (n > 7)
+ * {
+ * DEBUG_FUNC_STACKFRAME("n great than 7")
+ * ...
+ *
+ * }
+ *
+ * ...
+ *
+ * DEBUG_LOG("function bottom, n=%d", n)
+ *
+ * ...
+ * }
+ *
+ *
+ */
+
+
+#define DEBUG_FUNC_ENTRY DebugFuncEntry debug_func_obj(__FUNCTION__);
+
+#define DEBUG_FUNC_STACKFRAME(caption) DebugFuctStackFrame debug_func_inner(debug_func_obj, caption)
+
+#define DEBUG_LOG(fmt, args...) debug_printf("%s:%d:%s(): " fmt "\n", __FILE__, __LINE__, __FUNCTION__, ## args)
+
+
+/*!
+ * \brief printf-arguments function for print into debug log file.
+ * \param fmt
+ */
+extern void debug_printf(const char *fmt, ...);
+
+/*!
+ * \brief Print to log function entry and exit records.
+ *
+ */
+struct DebugFuncEntry {
+ static int level;
+ const char *func;
+ DebugFuncEntry(const char *f) :func(f) {
+ level++;
+ debug_printf("[%d] ---> %s()\n", level, func);
+ }
+ ~DebugFuncEntry() {
+ debug_printf("[%d] <--- %s()\n", level, func);
+ level--;
+ }
+ void enter(const char *caption) {
+ level++;
+ debug_printf("[%d] ---> %s() %s\n", level, func, caption);
+ }
+ void exit(const char *caption) {
+ debug_printf("[%d] <--- %s() %s\n", level, func, caption);
+ level--;
+ }
+};
+
+
+/*!
+ * \brief Object life-time logger.
+ *
+ * Derive your object from that class
+ * and you will get creation and delete object records.
+ */
+class DebugObjCreation {
+ DebugObjCreation() {
+ total++;
+ debug_printf("[create %d] Object created %p\n", total, this);
+ }
+ ~DebugObjCreation() {
+ debug_printf("[delete %d] Object deleted %p\n", total, this);
+ total--;
+ }
+private:
+ static int total;
+};
+
+
+/*!
+ * \brief Log for inner-function stack frames inside big function.
+ *
+ */
+class DebugFuncStackFrame {
+public:
+ DebugFuncStackFrame(DebugFuncEntry &obj, const char *capt)
+ : _obj(obj), _capt(capt) {
+ _obj.enter(_capt);
+ }
+ ~DebugFuncStackFrame() {
+ _obj.exit(_capt);
+ }
+private:
+ DebugFuncStackFrame();
+ DebugFuncEntry &_obj;
+ const char *_capt;
+};
+
diff -Naur ddrescue-1.17-rc4.orig/main_common.cc ddrescue-1.17-rc4/main_common.cc
--- ddrescue-1.17-rc4.orig/main_common.cc 2013-06-29 21:58:21.204574255 +0700
+++ ddrescue-1.17-rc4/main_common.cc 2013-06-29 22:00:30.792571529 +0700
@@ -176,7 +176,14 @@
const char * const binary_prefix[8] =
{ "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi" };
static bool si = true;
- static char buf[16];
+
+ // get static buffer from circle
+ const int BUFSIZE = 16;
+ const int NUMBUFS = 16;
+ static char bufs[NUMBUFS][BUFSIZE];
+ static int cur_buf = 0;
+ char *buf = bufs[cur_buf++];
+ cur_buf %= NUMBUFS;
if( set_prefix ) si = ( set_prefix > 0 );
const int factor = ( si ? 1000 : 1024 );
@@ -186,6 +193,6 @@
for( int i = 0; i < 8 && llabs( num ) > limit; ++i )
{ num /= factor; p = prefix[i]; }
- snprintf( buf, sizeof buf, "%lld %s", num, p );
+ snprintf( buf, BUFSIZE, "%lld %s", num, p );
return buf;
}
diff -Naur ddrescue-1.17-rc4.orig/Makefile.in ddrescue-1.17-rc4/Makefile.in
--- ddrescue-1.17-rc4.orig/Makefile.in 2013-06-29 21:58:21.200574255 +0700
+++ ddrescue-1.17-rc4/Makefile.in 2013-06-29 21:59:47.176572446 +0700
@@ -6,9 +6,9 @@
INSTALL_DIR = $(INSTALL) -d -m 755
SHELL = /bin/sh
-ddobjs = block.o fillbook.o genbook.o io.o logbook.o rescuebook.o main.o
+ddobjs = block.o fillbook.o genbook.o io.o logbook.o rescuebook.o main.o debug_print.o
objs = arg_parser.o rational.o $(ddobjs)
-logobjs = arg_parser.o block.o logbook.o ddrescuelog.o
+logobjs = arg_parser.o block.o logbook.o ddrescuelog.o debug_print.o
.PHONY : all install install-bin install-info install-man install-strip \
diff -Naur ddrescue-1.17-rc4.orig/rescuebook.cc ddrescue-1.17-rc4/rescuebook.cc
--- ddrescue-1.17-rc4.orig/rescuebook.cc 2013-06-29 21:58:21.204574255 +0700
+++ ddrescue-1.17-rc4/rescuebook.cc 2013-06-29 22:01:35.896570159 +0700
@@ -29,7 +29,7 @@
#include "block.h"
#include "ddrescue.h"
-
+#include "debug_print.h"
namespace {
@@ -82,6 +82,14 @@
if( errors_or_timeout() ) return 1;
if( interrupted() ) return -1;
int retval = copy_block( b, copied_size, error_size );
+
+ debug_printf("copy_and_update(): %10lld %c [0x%08llX,%10sB]: %10sB copied, %10sB errors.",
+ b.pos() / 512, char(st),
+ b.pos(), format_num(b.size()),
+ format_num(copied_size), format_num(error_size));
+ if (copied_size + error_size < b.size())
+ debug_printf("It has hit the EOF of input device/file");
+
if( !retval )
{
if( copied_size + error_size < b.size() ) // EOF
@@ -118,6 +126,7 @@
//
int Rescuebook::copy_non_tried()
{
+ DEBUG_FUNC_ENTRY
bool first_post = true;
for( bool first_pass = true; ; first_pass = false )
@@ -189,6 +198,7 @@
//
int Rescuebook::rcopy_non_tried()
{
+ DEBUG_FUNC_ENTRY
bool first_post = true;
for( bool first_pass = true; ; first_pass = false )
@@ -261,6 +271,7 @@
//
int Rescuebook::trim_errors()
{
+ DEBUG_FUNC_ENTRY
const char * const msg = "Trimming failed blocks...";
bool first_post = true;
@@ -324,6 +335,7 @@
//
int Rescuebook::split_errors( const bool reverse )
{
+ DEBUG_FUNC_ENTRY
const char * const msg = "Splitting failed blocks...";
bool first_post = true;
@@ -449,6 +461,7 @@
//
int Rescuebook::copy_errors()
{
+ DEBUG_FUNC_ENTRY
char msgbuf[80] = "Retrying bad sectors... Retry ";
const int msglen = std::strlen( msgbuf );
@@ -494,6 +507,7 @@
//
int Rescuebook::rcopy_errors()
{
+ DEBUG_FUNC_ENTRY
char msgbuf[80] = "Retrying bad sectors... Retry ";
const int msglen = std::strlen( msgbuf );
@@ -584,6 +598,9 @@
//
int Rescuebook::do_rescue( const int ides, const int odes, const bool reverse )
{
+ DEBUG_FUNC_ENTRY;
+ debug_printf("Debug: copy_and_update(): sector status block_start,block_size : copied_size, errors_size.");
+
bool copy_pending = false, trim_pending = false, split_pending = false;
ides_ = ides; odes_ = odes;