-
Notifications
You must be signed in to change notification settings - Fork 396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Edit atoe_sprintf to handle arguments of any length #6601
base: master
Are you sure you want to change the base?
WIP: Edit atoe_sprintf to handle arguments of any length #6601
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for supporting the project, and congratulations on your first contribution! A project committer will shortly review your contribution. In the mean time, if you haven't had a chance please skim over the contribution guidelines which all pull requests must adhere to. If the ECA pull request check fails, have a look at the instructions for signing the ECA in the legal considerations section.
If you run into any problems our community will be happy to assist you in any way we can. There are a number of recommended ways to interact with the community. We encourage you to ask questions, or drop by to say hello.
@babsingh : please review if this is within your purview. |
jenkins build all |
Reducing the perf costWith the below impl, the
|
util/a2e/atoe.c
Outdated
@@ -1342,12 +1343,20 @@ int | |||
atoe_sprintf(char *buf, char *ascii_chars, ...) | |||
{ | |||
int len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assign an initial value to each variable: https://github.com/eclipse/omr/blob/master/doc/CodingStandard.md#variable-declarations
int len; | |
int len = 0; |
util/a2e/atoe.c
Outdated
@@ -1342,12 +1343,20 @@ int | |||
atoe_sprintf(char *buf, char *ascii_chars, ...) | |||
{ | |||
int len; | |||
char wrkbuf[BUFLEN]; | |||
int argSize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int argSize; | |
int argSize = 0; |
util/a2e/atoe.c
Outdated
|
||
va_list args; | ||
va_list args, args_copy; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never declare more than one variable on a line: https://github.com/eclipse/omr/blob/master/doc/CodingStandard.md#variable-declarations
va_list args, args_copy; | |
va_list args; | |
va_list args_copy; |
|
||
len = atoe_vsnprintf(wrkbuf, BUFLEN, ascii_chars, args); | ||
len = atoe_vsnprintf(wrkbuf, argSize, ascii_chars, args); | ||
|
||
va_end(args); | ||
if (-1 == len) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strcpy((char *)buf, wrkbuf);
Will the strcpy
segfault if buf == NULL
(user-input)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, even with your suggested implementation for reducing performance costs, we will at least have to grab the length of the incoming arguments to decide if the "fast-path" option would fail
Not necessarily. See https://linux.die.net/man/3/vsnprintf.
The functions snprintf() and vsnprintf() do not write more than size bytes (including the terminating null byte ('\0')). If the output was truncated due to this limit then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated. (See also below under NOTES.)
Please confirm if the above statement is also true for our implementation.
If so, then the following should work:
len = atoe_vsnprintf(wrkbuf, BUFLEN, ascii_chars, args); if (len >= BUFLEN) { /* Truncated: take the slow path. */ }
Size of wrkbuf
must be defined before the call to vsnprintf
, this is why we grab the length of the incoming string before creating the char array. If the conditional you suggest passes, we would create another char array with the correct size. Is this acceptable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #6601 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it helps or not but with my changes to atoe_vsnprintf in this1 PR, it would behave more like std vsnprintf! for instance if you call it like atoe_vsnprintf(NULL, 0, format, arguments)
it would return estimate of how much space that operation would take without actually write to any buffer! (it was returning -1 before my PR)
util/a2e/atoe.c
Outdated
/* Add 1 to accommodate for null terminating char */ | ||
argSize = vsnprintf(NULL, 0, ebcdic_chars, args_copy) + 1; | ||
|
||
char wrkbuf[argSize]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
char wrkbuf[argSize]; | |
char wrkbuf[argSize] = {0}; |
util/a2e/atoe.c
Outdated
va_copy(args_copy, args); | ||
|
||
char *ebcdic_chars = a2e_string(ascii_chars); | ||
/* Add 1 to accommodate for null terminating char */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proper grammar should be enforced for comments.
/* Add 1 to accommodate for null terminating char */ | |
/* Add 1 to accommodate for the null terminating char. */ |
|
Not necessarily. See https://linux.die.net/man/3/vsnprintf.
Please confirm if the above statement is also true for our implementation. If so, then the following should work:
|
Stack allocating a
It will segfault if the If the
In libjli/java.c#L996, a string of sufficient size (
|
After some tests, I can confirm that Are you suggesting to grab the length of string A null check can be added for |
Can you elaborate? Does it return Based on atoe_utils.c#L587-L588, it should return the correct size of the string unless it is truncated. For tests, did you add print statements in
They already evaluate the length in java.c#L993. There are two different functions:
Ref: https://cplusplus.com/reference/cstdio/sprintf/. In the glibc implementation, |
Yes, sorry for misspeaking. To clarify,
I can confirm my test was adding print statements in
Ah I see, let me run some tests regarding this suggestion.
Heard |
@babsingh UPDATE: An internal PR was made regarding your suggestion of using There currently stands two possible options:
What are your thoughts on these approaches? Do you think it's worth it to explore editing |
I am in favour of the first approach.
In an online search, I found two different definitions of
V1 is only IBM specific whereas all others follow V2. V1 may have been documented incorrectly. If we decide to change our implementation from V1 to V2,
@joransiu Do you foresee any issues in changing our |
Just to make sure I'm following..... Even with the first approach, if the returned size on the
No, I scanned the code calling atoe_vsnprintf, and don't foresee any issues. I agree with approach to update the definition to V2. |
It actually depends on the compiler as per https://stackoverflow.com/a/10627731. Not sure what the behaviour is on Z-platforms. In I will leave it to @danjapapajani to do the experiments and determine the most efficient approach that is feasible. |
1ab5410
to
b945b80
Compare
UPDATE: committed new changes to
Overall, the only change I feel comfortable merging as of right now would be that of |
@danjapapajani Please rebase your commit so that unrelated changes don't appear in https://github.com/eclipse/omr/pull/6601/files . Thanks. |
…rguments of any length by: -Add variable in atoe_vsnprintf() to track the number of characters which would have been written to the final string if enough space had been available -Edit atoe_sprintf, atoe_fprintf, atoe_printf,atoe_vfprintf, and atoe_vsprintf to create a new char array with the correct size Signed-off-by: Danja Papajani <danja.papajani@ibm.com>
b945b80
to
131c8a7
Compare
|
||
ebuf = a2e(buf, len); | ||
va_end(args); | ||
if (-1 == len) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_buf
would need to be freed on this path prior to the return statement. There are similar cases in the other functions you updated.
@@ -496,6 +497,7 @@ atoe_vsnprintf(char *str, size_t count, const char *fmt, va_list args) | |||
goto next_char; | |||
case 's': | |||
strvalue = va_arg(args, char *); | |||
final_len += (int)strlen(strvalue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'll need to review and handle the final_len
calculations for all the other cases besides "%s".
@danjapapajani : That message suggests it's a limitation in the application you areusing to review the output file. What if you
Can you pipe the output into a file, and confirm the printf output is valid?
Why is that the case? |
This commit rewrites atoe_sprintf to handle string arguments of any length by:
Signed-off-by: Danja Papajani danja.papajani@ibm.com