Hi Stefan,
I'm using the arm gnu c cross compiler.
Yes, the apr configure script created the correct defines for the 64-bit
stuff.
FROM C99:
"
The macro INTN_C(value) shall expand to an integer constant expression
corresponding to the type int_leastN_t. The macro UINTN_C(value) shall
expand
to an integer constant expression corresponding to the type uint_leastN_t.
For
example, if uint_least64_t is a name for the type unsigned long long int,
then UINT64_C(0x123) might expand to the integer constant 0x123ULL.
"
It seems that APR_TIME_C(1000000) might expand to (long long).
Furthermore,
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
Thus we return long(4 bytes) * long long(8 bytes) + long(4 bytes)
Usual arithmetic conversions apply here, where the rank of long long int
shall be greater than the rank of long int.
So I agree with you, it should work without eksplicit type conversions.
I wrote a small test program which confirm you're right:
"
Conversion test
tv.tv_sec * APR_USEC_PER_SEC + tv.tv_usec
lld: 1294219141090251
(long long)tv.tv_sec * APR_USEC_PER_SEC + tv.tv_usec
lld: 1294219141090251
tv.tv_sec * (long long)APR_USEC_PER_SEC + tv.tv_usec
lld: 1294219141090251
tv.tv_sec * APR_USEC_PER_SEC + (long long)tv.tv_usec
lld: 1294219141090251
5-1-2011 10:19:0
"
Everything seems to work as expected, however, if I leave out my minor
typecast adjustments my subversion fails with bogus dates. I have no idea
why then.
Best regards,
René
-----Oprindelig meddelelse-----
From: Stefan Ruppert
Sent: Tuesday, January 04, 2011 6:12 PM
To: René Hjortskov Nielsen
Cc: [email protected]
Subject: Re: Fw: svnserve with corrupt timestamps and malformed text
representation
Hi Rene,
this fix is not needed. Since APR_USEC_PER_SEC is defined as
#define APR_USEC_PER_SEC APR_TIME_C(1000000)
using
#define APR_TIME_C(val) APR_INT64_C(val)
#define APR_INT64_C(val) INT64_C(val)
and INT64_C() is defined by C99. Thus it seems to me that your cross
compiler does not support C99 or is broken.
Are you sure that the apr configure script in conjunction with your
cross-compiler created the correct defines for 64-bit stuff?
Regards,
Stefan
René Hjortskov Nielsen wrote:
To whom it might interest.
Below is some observations concerning esspecially how apr calculates the
current time in apr_time_now and a minor bugfix suggestion.
Best regards,
René
-----Oprindelig meddelelse----- From: Daniel Shahaf
Sent: Tuesday, January 04, 2011 1:39 PM
To: RenéHjortskov Nielsen
Cc: [email protected]
Subject: Re: svnserve with corrupt timestamps and malformed text
representation
René Hjortskov Nielsen wrote on Tue, Jan 04, 2011 at 13:08:51 +0100:
Hopefully this is useful information for someone :)
It's useful, yes. You could pass this information directly to the APR
project: http://apr.apache.org/ should identify the mailing list you
need.
Thanks,
Daniel
René Hjortskov Nielsen wrote on Tue, Jan 04, 2011 at 13:08:51 +0100:
Thanks for your input.
I ended up debugging the subversion and apr code and found the solution.
I corrected the timestamps by making some typecasts in
subversion-1.6.13/apr/time/unix/time.c:
"
APR_DECLARE(apr_time_t) apr_time_now(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
// RHN: Need to typecast these in order to preserve 8 byte result,
otherwise it gets treated as 4 bytes.
return tv.tv_sec * (long long)APR_USEC_PER_SEC + (long
long)tv.tv_usec;
// return tv.tv_sec * APR_USEC_PER_SEC + tv.tv_usec;
}
"
Since we are multiplying with 1000000 here, we get a huge number for
instance
apr_time_t = 1294141942240251 as long long and with my typecasts
binary : 100 10011001 00000011 11100110 11000001 10010011
11111011
apr_time_t : -423521285 without typecasts, apparently represented as a
4 byte type which can hold 4294967295 as the largest positive number.
4294967295 = 11111111 11111111 11111111 11111111
Hence it should be safe to add the above typecasts to the trunk in the
apr code, because the needed size of the timestamp will be the same on a
32-bit machine aswell on a 64-bit machine.
However, this only fixed the timestamp generation and not the string
generation for the --log-file directive.
Thus removing the error:
"
Bogus date
"
The solution here was also easy and I found that the apr.h file generated
by configure had the wrong output form:
"
/* And APR_OFF_T_FMT */
#define APR_OFF_T_FMT "ld"
//?? APR_INT64_T_FMT
/* And APR_PID_T_FMT */
#define APR_PID_T_FMT "ld"
//?? APR_INT64_T_FMT
"
Basically, I changed the formatters from lld to ld. Please note that I
had to do the same for APR_OFF_T_FMT, which also was formatted wrong.
This fixes the svn import, commit or mkdir error stating:
"
svn: Corrupt node-revision '0.0.t0-1'
svn: Malformed text representation offset line in node-rev
"
I'm not sure that these apr.h changes are universal changes, mainly due
to off_t being defined as 4 bytes and sometimes as 8 bytes.
Hopefully this is useful information for someone :)
Best regards,
René
-----Oprindelig meddelelse----- From: Daniel Shahaf
Sent: Saturday, January 01, 2011 12:38 PM
To: RenéHjortskov Nielsen
Cc: [email protected]
Subject: Re: svnserve with corrupt timestamps
René Hjortskov Nielsen wrote on Sat, Jan 01, 2011 at 09:51:57 +0100:
I’ve cross compiled subversion 1.6.15 on my i686 to the target system
armv4l (product ib-nas3221-b).
Everything seems to work, I can work with my old repository which has
been moved to the target system.
However, when I do a commit through svnserve running on the target I
get the commonly known and unresolved “bug” Bogus date.
I have tested that this is not the case when using the repository with
my client (TortoiseSVN) directly, i.e. file protocol.
I have noticed that all svnserve timestamps are bad, even in the
logfile when running svnserve with –log-file.
Here are some sample logfile timestamps from svnserve:
5191 1969-12-31T23:57:53.-414901Z 192.168.5.4 xx newrepo open 2
cap=(edit-pipeline svndiff1 absent-entries depth mergeinfo
log-revprops) / SVN/1.6.15%20(r1038135) -
5191 1969-12-31T23:57:53.-404901Z 192.168.5.4 xx newrepo get-latest-rev
5191 1969-12-31T23:57:53.-394901Z 192.168.5.4 xx newrepo reparent /
5191 1969-12-31T23:57:53.-394901Z 192.168.5.4 xx newrepo stat /@0
5192 1969-12-31T23:57:53.-334901Z 192.168.5.4 xx newrepo open 2
cap=(edit-pipeline svndiff1 absent-entries depth mergeinfo
log-revprops) / SVN/1.6.15%20(r1038135) -
Date on my target server with date command was:
Sat Dec 31 14:03:57 CST 2010
On a commit through svnserve the same bogus dates are written
everywhere, rendering the repository unsuable, i.e.
newrepo/db/revprops/0/1
I am woundering if this is a 32-/64-bit issue, even though both my i686
build system and the armv4l target system are 32-bit editions.
The date is parsed into an apr_time_t, which is a 64-bit type
(in APR 1.4.2).
Exactly how is the date supposed to be generated in svnserve?
During commits, the client sends the would-be revprops to the server.
But the server overrides svn:date and svn:author and computes them
itself.
At some point, all revprops undergo validation (see validate_prop() in
subversion/libsvn_repos/fs-wrap.c), one of those validations being that
svn:date's value is in the expected machine-readable format:
% svn pg --revprop -rHEAD svn:date
http://svn.apache.org/repos/asf/subversion
2011-01-01T11:33:37.147038Z
Currently my understanding is that dates are mapped back and forth from
human readable formats to machine format, thus I suspect that this
could be the source of the problem.
Unfortunately I do not have the time to start writing debug code to
isolate the problem at hand and was hoping that someone with enough
insight could provide the debug code, which I happily will recompile
and test.
Best regards and a happy new year,
René