[Vm-dev] patch for subversion (classical VM) primitiveLocalMicroseconds

David T. Lewis lewis at mail.msen.com
Thu Apr 22 21:35:52 UTC 2021


Hi David,

Sorry have not had time to respond to this yet, but I'm definitely
interested in the fix.

Thanks,
Dave


On Tue, Apr 20, 2021 at 07:27:27PM +0200, stes at PANDORA.BE wrote:
> 
> Hi,
> 
> This is a patch for subversion squeakvm 4.19.6.
> 
> It relates to the primitiveLocalMicrosecondClock.
> 
> It does not affect OpenSmalltalk (I think the code in OpenSmalltalk
> is different and is not affected by the following problem).
> 
> I'm not sure it is actually desired at all to implement
> primitiveLocalMicrosecondClock in the 32bit case in the classical SqueakVM,
> but if it is, there is an arithmetical overflow on my platform (Solaris 32bit).
> 
> I don't think it affects the classical SqueakVM Solaris 64bit by the way,
> (for the 68000 type of Smalltalk images).
> 
> The patch is for the file platforms/unix/vm/sqUnixMain.c
> function sqUnixUtcWithOffset().
> 
> This function is doing:
> 
>   time_t seconds= timeval.tv_sec;
>   suseconds_t usec= timeval.tv_usec;
>   *microSeconds= seconds * 1000000 + usec;
> 
> unfortunately the multiplication (seconds * 1000000) is triggering overflow.
> 
> The type time_t is defined for me as:
> typedef long    time_t;
> typedef	long	suseconds_t;	/* signed # of microseconds */
> 
> Note that I believe that in the 32bit case this has size 4 bytes
> and in the 64bit case this has size 8 bytes (for me on Solaris).
> 
> So Solaris 64bit is not affected by the multiplication error, but 32bit is.
> 
> I propose the following patch:
> 
> Index: vm/sqUnixMain.c
> ===================================================================
> - --- vm/sqUnixMain.c	(revision 3799)
> +++ vm/sqUnixMain.c	(working copy)
> @@ -213,11 +213,13 @@
>   */
>  sqInt sqUnixUtcWithOffset(sqLong *microSeconds, int *offset)
>  {
> +  sqLong theMicroSeconds;
>    struct timeval timeval;
>    if (gettimeofday(&timeval, NULL) == -1) return -1;
>    time_t seconds= timeval.tv_sec;
>    suseconds_t usec= timeval.tv_usec;
> - -  *microSeconds= seconds * 1000000 + usec;
> +  theMicroSeconds = seconds;
> +  *microSeconds= theMicroSeconds * 1000000 + usec;
> 
> The rationale is that the function seems to assume anyway that it is possible
> to store the result in *microSeconds which is of type sqLong.
> 
> So by defining a local variable theMicroSeconds and casting seconds to that
> type, and then multiplying (instead of 32bit multiply, on the 64bit),
> it may work ...  at least it seems to work for me.
> 
> Maybe an alternative could be simply NOT to implement 
> primitiveLocalMicrosecondClock in the 32bit case ...
> 
> If primitiveLocalMicrosecondClock would return nil (primitiveFail) in the 32bit
> case, it would also be a possible solution.
> 
> The primitive assumes anyway that it returns the microseconds as LargeInteger.
> 
> David Stes
> 
> PS1: in attach the patch to apply if desired
> 
> PS2: I've tested this on Solaris - all platforms are affected;
> it is hard to say for me how other platforms are affected,
> given their time_t definition and their sqLong definition.
> 
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v2
> 
> iQEcBAEBCAAGBQJgfw4nAAoJENdFDkXGicizFVQH/3GhR/K0K9H9AyS4uBCeEIxg
> lv4rCq2w9tXWeLP8eUc50sJnAsK7UVnO6FUpdFmF0qauN0414C5KmrQcIivNoEvH
> kMiWduIWXfzX7VlHj56pyuYym73qOZDZowFOvnPjaVQfKcqC9yyabYrEF7THc8j3
> F8bVwCy/oz1h9/Mi6VbCrjz1G+ePmowXiv5vkJFAwQDNGrc53OyhQm6Wfibdwb/8
> 6C2C/loPeStDf9f3Y3zhIkelp0RI4TL+h+D+REaf0kWV/TubIx648hcP4uvBhyQk
> 6hwD7OHHechkJLgYAni1ipGXfX03cAM2plLIgKHahypNz1mVcZhu/6SSMTQK1ik=
> =gf1g
> -----END PGP SIGNATURE-----



More information about the Vm-dev mailing list