Re: [Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-07 Thread andrey simiklit
On Thu, Sep 6, 2018 at 3:20 PM Emil Velikov 
wrote:

> Hi Andrii,
>
> I think you might be overthinking my comments.
> There's nothing special, nor am I trying to force my opinion.
>
> If you think my suggestions make sense, great. Otherwise don't bother too
> much.
>
Thanks a lot for your advices and reviewing)

>
> HTH
> Emil
>
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-06 Thread Emil Velikov
Hi Andrii,

I think you might be overthinking my comments.
There's nothing special, nor am I trying to force my opinion.

If you think my suggestions make sense, great. Otherwise don't bother too much.

HTH
Emil
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-06 Thread asimiklit.w...@gmail.com

Hello,

Thanks for your reply.

The 'util_vsnprintf' function under Linux is just an alias for 'vsnprintf':

#define util_vsnprintf vsnprintf

So as far as I understood we should ensure compatibility between
'vsnprintf' function under Linux and '_vsnprintf' function under Windows using
our wrapper to be able to use 'util_vsnprintf' in the similar way
on different platforms.

Could you please share your thoughts about it?

So going back to:


static inline int
util_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
   /* We need to use _vscprintf to calculate the length as vsnprintf returns
-1
* if the number of characters to write is greater than count.
*/
   va_list ap_copy;
   int ret;
   va_copy(ap_copy, ap);


The 'ap_copy' and 'ap' both are valid here.
One of them can't affect other one.
So the invalidation of 'ap' should not affect 'ap_copy' and vice versa

MSDN https://msdn.microsoft.com/en-us/library/kb57fad8.aspx :
 "va_copy makes a copy of a list of arguments in its current state.
  The src parameter must already be initialized with va_start; it may have been 
updated with va_arg calls,
  but must not have been reset with va_end.
  The next argument that's retrieved by va_arg from dest is the same as the next 
argument that's retrieved from src."

Please correct me if I am incorrect.


   ret = _vsnprintf(str, size, format, ap);


The 'ap_copy' is valid but 'ap' is invalid here.

Could you please correct me if I am incorrect.

task 2: use the copied va  


Could you please explain the reason?
if you want to avoid the invalidation of original 'ap' parameter it will work 
on windows
but Linux uses the original 'vsnprintf' function which anyway invalidates it.
Do you want to implement some wrapper instead of:
#define util_vsnprintf vsnprintf
for Linux to avoid invalidation of 'ap'?


   if (ret < 0) {
  ret = _vscprintf(format, ap_copy);


The 'ap_copy' is invalid here


   }
+   va_end(ap_copy);


MSDN:
 "va_end must be called on each argument list that's initialized
  with va_start or va_copy before the function returns."


   return ret;
}




How I explained above it is needed because
we can not pass the same instance of 'va_list' to multiple functions
because 'va_list' instance can be changed by the called function.

I will send new patch as soon as we came agreement about it.

Please correct me if I am incorrect.


You are correct. I'm saying that you're fixing things in the wrong order.
Which could easily cause problems.


I unable to find any problems with 'va_end' which releases local resource.
The behavior of original 'va_list' parameter called 'ap'
will not be changed by the 'va_end' function which is applied to the copy of it.
So as far as I understood for the callers/users of the 'util_vsnprintf' nothing 
will be changed.
Could you please share your thoughts about it?
Could you please provide some example how it could cause problems?


2. use the copied va when using util_vsnprintf and in the u_string.h

You mean to use 'va_copy' for the each 'util_vsnprintf' function usage
in mesa source code? I do not see reasons for that.

Grepping through for "va_copy" and checking the new one is actually used shows:
src/glx/apple/apple_glx_log.c -> missing va_end


I agree. I will provide a patch for this case.


src/intel/tools/imgui/imgui.cpp -> using the orig va, then the copy


It seems correct for me.
   'orig va' is used for a first call
   'copy' is used for another call


src/util/u_string.h: util_vsnprintf -> using the orig va, then the copy


It seems correct for me.
   'orig va' is used for a first call
   'copy' is used for another call

Could you please correct me if I am incorrect.


src/util/u_string.h: util_vasprintf -> using the orig va


I agree. 'copy' is created but 'orig va' is used for both calls.
I will provide a patch for this case.


Regards,
Andrii.

On 05.09.18 15:52, Emil Velikov wrote:


On 5 September 2018 at 13:03, asimiklit.w...@gmail.com
 wrote:

Hello,

Thanks for your reply.

I think that we just misunderstand each other)

static inline int
util_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
/* We need to use _vscprintf to calculate the length as vsnprintf returns
-1
 * if the number of characters to write is greater than count.
 */
va_list ap_copy;
int ret;
va_copy(ap_copy, ap);
ret = _vsnprintf(str, size, format, ap);

task 2: use the copied va

if (ret < 0) {
   ret = _vscprintf(format, ap_copy);
}
+   va_end(ap_copy);
return ret;
}

As far as I understand this fix will just release the resource which was
allocated locally.

If you care about an 'va_list' invalidation after call of 'util_vsnprintf'
function
it works as was. The same result will be on Linux with 'vsnprintf'.
Please pay attention that the 'va_end' function is called
only for a copy of input argument not for original.

I guess it can not cause problems.

Please correct me If I am incorrect.


Reasonable 

Re: [Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-05 Thread Emil Velikov
On 5 September 2018 at 13:03, asimiklit.w...@gmail.com
 wrote:
> Hello,
>
> Thanks for your reply.
>
> I think that we just misunderstand each other)
>
> static inline int
> util_vsnprintf(char *str, size_t size, const char *format, va_list ap)
> {
>/* We need to use _vscprintf to calculate the length as vsnprintf returns
> -1
> * if the number of characters to write is greater than count.
> */
>va_list ap_copy;
>int ret;
>va_copy(ap_copy, ap);
>ret = _vsnprintf(str, size, format, ap);
task 2: use the copied va
>if (ret < 0) {
>   ret = _vscprintf(format, ap_copy);
>}
> +   va_end(ap_copy);
>return ret;
> }
>
> As far as I understand this fix will just release the resource which was
> allocated locally.
>
> If you care about an 'va_list' invalidation after call of 'util_vsnprintf'
> function
> it works as was. The same result will be on Linux with 'vsnprintf'.
> Please pay attention that the 'va_end' function is called
> only for a copy of input argument not for original.
>
> I guess it can not cause problems.
>
> Please correct me If I am incorrect.
>
Reasonable assumption, which I would [personally] not dare to make
since we're talking about MSVC and C99 compliance.
Looking at MSDN

Beginning with the UCRT in Visual Studio 2015 and Windows 10,
vsnprintf is no longer identical to _vsnprintf. The vsnprintf function
complies with the C99 standard; _vnsprintf is retained for backward
compatibility with older Visual Studio code.

We have various workarounds for missing va_copy [and in general string
handling] which one gets picked where is fairly magical.

> 1. fix util_vsnprintf users which do not va_copy
>
> I found just one case in the mesa source code where 'va_copy'
> should be added. It is in 'util_vasprintf' function.
> Actually there already is the copy of va but for some reason it is not used.
> https://cgit.freedesktop.org/mesa/mesa/tree/src/util/u_string.h#n121
>
Right, I've noticed that one and didn't look if there are more.

> 2. use the copied va when using util_vsnprintf and in the u_string.h
>
> You mean to use 'va_copy' for the each 'util_vsnprintf' function usage
> in mesa source code? I do not see reasons for that.
>
Grepping through for "va_copy" and checking the new one is actually used shows:
src/glx/apple/apple_glx_log.c -> missing va_end
src/intel/tools/imgui/imgui.cpp -> using the orig va, then the copy
src/util/u_string.h: util_vsnprintf -> using the orig va, then the copy
src/util/u_string.h: util_vasprintf -> using the orig va

> (optional) 4. replace opencoded instances of util_vsnprintf
>
> Do you mean find all places where 'vsnprintf' function is used directly
> and replace it by our more compatible 'util_vsnprintf'?
> Like following example:
> https://cgit.freedesktop.org/mesa/mesa/tree/src/mesa/main/imports.c#n256
>
> #ifdef _WIN32
> #define vsnprintf _vsnprintf
> #else
> 
> int
> _mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list args)
> {
>return vsnprintf( str, size, fmt, args);
> }
>
> I think it is good idea because win32 '_vsnprintf' function works a bit
> differently
> at least for case when the input buffer size less than the required size:
> windows '_vsnprintf' will return -1 for this case.
> linux 'vsnprintf' will return the required size.
>
That's one case, yes. Skimming through src/intel there is a bunch of
va_start + vsnprintf + va_end which could be swapped with
util_s[n]printf.

HTH
Emil

> P.S. Please use plan-text + interleaved quoting when working with mailing
> lists.
>
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-05 Thread asimiklit.w...@gmail.com

Hello,

Thanks for your reply.

I think that we just misunderstand each other)


static inline int
util_vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
/* We need to use _vscprintf to calculate the length as vsnprintf returns -1
 * if the number of characters to write is greater than count.
 */
va_list ap_copy;
int ret;
va_copy(ap_copy, ap);
ret = _vsnprintf(str, size, format, ap);
if (ret < 0) {
   ret = _vscprintf(format, ap_copy);
}
+*va_end(ap_copy);*
return ret;
}


As far as I understand this fix will just release the resource which was 
allocated locally.
 
If you care about an 'va_list' invalidation after call of 'util_vsnprintf' function

it works as was. The same result will be on Linux with 'vsnprintf'.
Please pay attention that the 'va_end' function is called
only for a copy of input argument not for original.

I guess it can not cause problems.

Please correct me If I am incorrect.


1. fix util_vsnprintf users which do not va_copy


I found just one case in the mesa source code where 'va_copy'
should be added. It is in 'util_vasprintf' function.
Actually there already is the copy of va but for some reason it is not used.
https://cgit.freedesktop.org/mesa/mesa/tree/src/util/u_string.h#n121


2. use the copied va when using util_vsnprintf and in the u_string.h


You mean to use 'va_copy' for the each 'util_vsnprintf' function usage
in mesa source code? I do not see reasons for that.


(optional) 4. replace opencoded instances of util_vsnprintf


Do you mean find all places where 'vsnprintf' function is used directly
and replace it by our more compatible 'util_vsnprintf'?
Like following example:
https://cgit.freedesktop.org/mesa/mesa/tree/src/mesa/main/imports.c#n256

#ifdef _WIN32 #define vsnprintf _vsnprintf #else  
int _mesa_vsnprintf(char *str, size_t size, const char *fmt, va_list 
args) { return vsnprintf( str, size, fmt, args); }


I think it is good idea because win32 '_vsnprintf' function works a bit 
differently
at least for case when the input buffer size less than the required size:
windows '_vsnprintf' will return -1 for this case.
linux 'vsnprintf' will return the required size.


Normally you'd want separate patches for each piece. Wrt 4. might even
split per-subsystem.


It is good idea.

Regards,
Andrii.

On 04.09.18 23:49, Emil Velikov wrote:


On 4 September 2018 at 10:04, andrey simiklit  wrote:

Hi,

Thanks for your reply.


These WIN32 compat functions seem iffy.
Namely - often we'll issue a va_copy only to use the original va.


As far as I found there is the following reason to use va_copy:

https://linux.die.net/man/3/vsnprintf
"These functions do not call the va_end macro. Because they
   invoke the va_arg  macro, the value of ap is undefined after the call"

http://www.cplusplus.com/reference/cstdio/vsnprintf/
"nternally, the function retrieves arguments from the list identified by arg
as
  if va_arg was used on it, and thus the state of arg is likely to be altered
by the call."

but unfortunately nothing about it on MSDN
so I presume the worst case - it works in the same way.

So the main reason to use va_copy it is when we need pass
our 'va_list' instance to more then one functions because the 'va_list'
instance
can be changed by the called function.

I think that the 'util_vasprintf' on line 116 also should be fixed
because it creates the the copy of 'va_list' but passes
the original 'va_list' instance into both function.


Looking through the rest of the code base:
There are plenty of va_start + util_vsnprintf + va_free cases that
could be replaced with util_snprintf.


I think that I misunderstand you here.
I don't know way to do it. For example:

static inline void
trace_dump_writef(const char *format, ...)
{
static char buf[1024];
unsigned len;
va_list ap;
va_start(ap, format);
len = util_vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
trace_dump_write(buf, len);
}

if I try to replace 3 lines above by util_snprintf what should I pass to
parameter '...' ?
Could you please give me an example how to do it?


There are also some util_vsnprintf users which use va_copy and some
who do not :-\


How I explained above it is needed because
we can not pass the same instance of 'va_list' to multiple functions
because 'va_list' instance can be changed by the called function.

I will send new patch as soon as we came agreement about it.

Please correct me if I am incorrect.


You are correct. I'm saying that you're fixing things in the wrong order.
Which could easily cause problems.

1. fix util_vsnprintf users which do not va_copy
2. use the copied va when using util_vsnprintf and in the u_string.h
3. add the missing va_end - the original patch
(optional) 4. replace opencoded instances of util_vsnprintf

Normally you'd want separate patches for each piece. Wrt 4. might even
split per-subsystem.

HTH
Emil
P.S. Please use plan-text + interleaved quoting when 

Re: [Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-04 Thread Emil Velikov
On 4 September 2018 at 10:04, andrey simiklit  wrote:
> Hi,
>
> Thanks for your reply.
>
>> These WIN32 compat functions seem iffy.
>> Namely - often we'll issue a va_copy only to use the original va.
>
>
> As far as I found there is the following reason to use va_copy:
>
> https://linux.die.net/man/3/vsnprintf
> "These functions do not call the va_end macro. Because they
>   invoke the va_arg  macro, the value of ap is undefined after the call"
>
> http://www.cplusplus.com/reference/cstdio/vsnprintf/
> "nternally, the function retrieves arguments from the list identified by arg
> as
>  if va_arg was used on it, and thus the state of arg is likely to be altered
> by the call."
>
> but unfortunately nothing about it on MSDN
> so I presume the worst case - it works in the same way.
>
> So the main reason to use va_copy it is when we need pass
> our 'va_list' instance to more then one functions because the 'va_list'
> instance
> can be changed by the called function.
>
> I think that the 'util_vasprintf' on line 116 also should be fixed
> because it creates the the copy of 'va_list' but passes
> the original 'va_list' instance into both function.
>
>> Looking through the rest of the code base:
>> There are plenty of va_start + util_vsnprintf + va_free cases that
>> could be replaced with util_snprintf.
>
>
> I think that I misunderstand you here.
> I don't know way to do it. For example:
>>
>> static inline void
>> trace_dump_writef(const char *format, ...)
>> {
>>static char buf[1024];
>>unsigned len;
>>va_list ap;
>>va_start(ap, format);
>>len = util_vsnprintf(buf, sizeof(buf), format, ap);
>>va_end(ap);
>>trace_dump_write(buf, len);
>> }
>
> if I try to replace 3 lines above by util_snprintf what should I pass to
> parameter '...' ?
> Could you please give me an example how to do it?
>
>> There are also some util_vsnprintf users which use va_copy and some
>> who do not :-\
>
>
> How I explained above it is needed because
> we can not pass the same instance of 'va_list' to multiple functions
> because 'va_list' instance can be changed by the called function.
>
> I will send new patch as soon as we came agreement about it.
>
> Please correct me if I am incorrect.
>
You are correct. I'm saying that you're fixing things in the wrong order.
Which could easily cause problems.

1. fix util_vsnprintf users which do not va_copy
2. use the copied va when using util_vsnprintf and in the u_string.h
3. add the missing va_end - the original patch
(optional) 4. replace opencoded instances of util_vsnprintf

Normally you'd want separate patches for each piece. Wrt 4. might even
split per-subsystem.

HTH
Emil
P.S. Please use plan-text + interleaved quoting when working with mailing lists.
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-04 Thread andrey simiklit
Hi,

Thanks for your reply.

These WIN32 compat functions seem iffy.
> Namely - often we'll issue a va_copy only to use the original va.
>

As far as I found there is the following reason to use va_copy:

https://linux.die.net/man/3/vsnprintf
"These functions do not call the va_end macro. Because they
  invoke the va_arg  macro, the value of ap is *undefined after the call*"

http://www.cplusplus.com/reference/cstdio/vsnprintf/
"nternally, the function retrieves arguments from the list identified by
arg as
 if va_arg was used on it, and thus the state of *arg is likely to be
altered by the call.*"

but unfortunately nothing about it on MSDN
so I presume the worst case - it works in the same way.

So the main reason to use va_copy it is when we need pass
our 'va_list' instance to more then one functions because the 'va_list'
instance
can be changed by the called function.

I think that the 'util_vasprintf' on line 116 also should be fixed
because it creates the the copy of 'va_list' but passes
the original 'va_list' instance into both function.

Looking through the rest of the code base:
> There are plenty of va_start + util_vsnprintf + va_free cases that
> could be replaced with util_snprintf.
>

I think that I misunderstand you here.
I don't know way to do it. For example:
>
> static inline void
> trace_dump_writef(const char *format, ...)
> {
>static char buf[1024];
>unsigned len;
>va_list ap;
>va_start(ap, format);
>len = util_vsnprintf(buf, sizeof(buf), format, ap);
>va_end(ap);
>trace_dump_write(buf, len);
> }
>
if I try to replace 3 lines above by util_snprintf what should I pass to
parameter '...' ?
Could you please give me an example how to do it?

There are also some util_vsnprintf users which use va_copy and some
> who do not :-\
>

How I explained above it is needed because
we can not pass the same instance of 'va_list' to multiple functions
because 'va_list' instance can be changed by the called function.

I will send new patch as soon as we came agreement about it.

Please correct me if I am incorrect.

Regards,
Andrii.

On Mon, Sep 3, 2018 at 6:27 PM Emil Velikov 
wrote:

> On 3 September 2018 at 15:49,   wrote:
> > From: Andrii Simiklit 
> >
> > MSDN:
> > "va_end must be called on each argument list that's initialized
> >  with va_start or va_copy before the function returns."
> >
> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107810
> > Signed-off-by: Andrii Simiklit 
> >
> > ---
> >  src/util/u_string.h | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/src/util/u_string.h b/src/util/u_string.h
> > index ce45430..883fa64 100644
> > --- a/src/util/u_string.h
> > +++ b/src/util/u_string.h
> > @@ -81,6 +81,7 @@ util_vsnprintf(char *str, size_t size, const char
> *format, va_list ap)
> > if (ret < 0) {
> >ret = _vscprintf(format, ap_copy);
> > }
> > +   va_end(ap_copy);
> > return ret;
>
> These WIN32 compat functions seem iffy.
> Namely - often we'll issue a va_copy only to use the original va.
>
> Looking through the rest of the code base:
> There are plenty of va_start + util_vsnprintf + va_free cases that
> could be replaced with util_snprintf.
>
> There are also some util_vsnprintf users which use va_copy and some
> who do not :-\
>
> I think those should be looked first, otherwise adding this va_end
> could easily break things.
>
> HTH
> Emil
>
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-03 Thread Emil Velikov
On 3 September 2018 at 15:49,   wrote:
> From: Andrii Simiklit 
>
> MSDN:
> "va_end must be called on each argument list that's initialized
>  with va_start or va_copy before the function returns."
>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107810
> Signed-off-by: Andrii Simiklit 
>
> ---
>  src/util/u_string.h | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/src/util/u_string.h b/src/util/u_string.h
> index ce45430..883fa64 100644
> --- a/src/util/u_string.h
> +++ b/src/util/u_string.h
> @@ -81,6 +81,7 @@ util_vsnprintf(char *str, size_t size, const char *format, 
> va_list ap)
> if (ret < 0) {
>ret = _vscprintf(format, ap_copy);
> }
> +   va_end(ap_copy);
> return ret;

These WIN32 compat functions seem iffy.
Namely - often we'll issue a va_copy only to use the original va.

Looking through the rest of the code base:
There are plenty of va_start + util_vsnprintf + va_free cases that
could be replaced with util_snprintf.

There are also some util_vsnprintf users which use va_copy and some
who do not :-\

I think those should be looked first, otherwise adding this va_end
could easily break things.

HTH
Emil
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] mesa/util: add missing va_end() after va_copy()

2018-09-03 Thread asimiklit . work
From: Andrii Simiklit 

MSDN:
"va_end must be called on each argument list that's initialized
 with va_start or va_copy before the function returns."

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=107810
Signed-off-by: Andrii Simiklit 

---
 src/util/u_string.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/util/u_string.h b/src/util/u_string.h
index ce45430..883fa64 100644
--- a/src/util/u_string.h
+++ b/src/util/u_string.h
@@ -81,6 +81,7 @@ util_vsnprintf(char *str, size_t size, const char *format, 
va_list ap)
if (ret < 0) {
   ret = _vscprintf(format, ap_copy);
}
+   va_end(ap_copy);
return ret;
 }
 
-- 
2.7.4

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev