When running valgrind to check for errors in a program written in C89/90, it comes up with a Uninitialised value was created by a heap allocation error for a strToUpper() function I wrote, despite the string being initialised.
I'm using this function to compare strings ignoring case. Unfortunately, C89 doesn't seem to include the strcasecmp() function in <string.h>, so I've written my own, which calls the strToUpper() and strcmp() functions.
CODE
char* strToUpper(char* inStr)
{
int i;
char *upperStr;
size_t strLen = strlen(inStr);
upperStr = (char*)malloc(sizeof(char) * (strLen + 1));
/* Does this for loop not initialise upperStr? */
for (i = 0; i < strLen; i++)
upperStr[i] = toupper(inStr[i]);
return upperStr;
}
VALGRIND ERROR
==27== Conditional jump or move depends on uninitialised value(s)
==27== at 0x4C31FAA: strcmp (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27== by 0x406649: strcasecmp (stringPlus.c:178)
==27== ...
==27== by 0x400FEB: main (main.c:58)
==27== Uninitialised value was created by a heap allocation
==27== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==27== by 0x4062E4: strToUpper (stringPlus.c:58)
==27== by 0x406622: strcasecmp (stringPlus.c:175)
==27== ...
==27== by 0x400FEB: main (main.c:58)
Any ideas?
You are not terminating your copied string.
Add something like
upperStr[i] = '\0';
after your for loop.
Instead of using malloc(blah) I always use calloc(1,blah). The latter sets all allocated memory to zero.
Related
Thread 1 has code like this...
pthread_mutex_lock(&mtx);
...
buffers[cnt] = malloc(...); // cnt is global, volatile int
buffers[cnt]->field1 = ...;
buffers[cnt]->field2 = ...;
...
buffers[cnt]->fieldN = ...;
_mm_sfence(); // let's flush things for good measure
cnt++;
pthread_mutex_unlock(&mtx);
And thread 2:
// No sync
for(int i=0; i<cnt; i++) {
SomeType *p = buffers[i];
// use p->fieldX
}
In a Thread Sanitizer-built binary, I get a warning about the read of buffers[i] against the write (the result of the malloc).
It is true that the code in thread 2 doesn't use the mutex - but I am thinking that cnt will only be incremented when the new "slot" in buffers is all set; so I would expect that the for loop in thread 2 would only ever manage to read pointers that point to valid data. cnt is an integer; in 64-bit x86 you can't have a "half-updated" cnt; it either has the old value, or the new one, by which time that index points to valid data.
Simply put, I don't think there's a race - yet the thread sanitizer reports one.
Am I wrong?
Since two days I am trying to make printf\sprintf working in my project...
MCU: STM32F722RETx
I tried to use newLib, heap3, heap4, etc, etc. nothing works. HardFault_Handler is run evry time.
Now I am trying to use simple implementation from this link and still the same problem. I suppose my device has some problem with double numbers, becouse program run HardFault_Handler from this line if (value != value) in _ftoa function.( what is strange because this stm32 support FPU)
Do you guys have any idea? (Now I am using heap_4.c)
My compiller options:
target_compile_options(${PROJ_NAME} PUBLIC
$<$<COMPILE_LANGUAGE:CXX>:
-std=c++14
>
-mcpu=cortex-m7
-mthumb
-mfpu=fpv5-d16
-mfloat-abi=hard
-Wall
-ffunction-sections
-fdata-sections
-O1 -g
-DLV_CONF_INCLUDE_SIMPLE
)
Linker options:
target_link_options(${PROJ_NAME} PUBLIC
${LINKER_OPTION} ${LINKER_SCRIPT}
-mcpu=cortex-m7
-mthumb
-mfloat-abi=hard
-mfpu=fpv5-sp-d16
-specs=nosys.specs
-specs=nano.specs
# -Wl,--wrap,malloc
# -Wl,--wrap,_malloc_r
-u_printf_float
-u_sprintf_float
)
Linker script:
/* Highest address of the user mode stack */
_estack = 0x20040000; /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
UPDATE:
I don't think so it is stack problem, I have set configCHECK_FOR_STACK_OVERFLOW to 2, but hook function is never called. I found strange think: This soulution works:
float d = 23.5f;
char buffer[20];
sprintf(buffer, "temp %f", 23.5f);
but this solution not:
float d = 23.5f;
char buffer[20];
sprintf(buffer, "temp %f",d);
No idea why passing variable by copy, generate a HardFault_Handler...
You can implement a hard fault handler that at least will provide you with the SP location to where the issue is occurring. This should provide more insight.
https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html
It should let you know if your issue is due to a floating point error within the MCU or if it is due to a branching error possibly caused by some linking problem
I also had error with printf when using FreeRTOS for my SiFive HiFive Rev B.
To solve it, I rewrite _fstat and _write functions to change output function of printf
/*
* Retarget functions for printf()
*/
#include <errno.h>
#include <sys/stat.h>
int _fstat (int file, struct stat * st) {
errno = -ENOSYS;
return -1;
}
int _write (int file, char * ptr, int len) {
extern int uart_putc(int c);
int i;
/* Turn character to capital letter and output to UART port */
for (i = 0; i < len; i++) uart_putc((int)*ptr++);
return 0;
}
And create another uart_putc function for UART0 of SiFive HiFive Rev B hardware:
void uart_putc(int c)
{
#define uart0_txdata (*(volatile uint32_t*)(0x10013000)) // uart0 txdata register
#define UART_TXFULL (1 << 31) // uart0 txdata flag
while ((uart0_txdata & UART_TXFULL) != 0) { }
uart0_txdata = c;
}
The newlib C-runtime library (used in many embedded tool chains) internally uses it's own malloc-family routines. newlib maintains some internal buffers and requires some support for thread-safety:
http://www.nadler.com/embedded/newlibAndFreeRTOS.html
hard fault can caused by unaligned Memory Access:
https://www.keil.com/support/docs/3777.htm
I have a trivial program:
int main(void)
{
const char sname[]="xxx";
sem_t *pSemaphor;
if ((pSemaphor = sem_open(sname, O_CREAT, 0644, 0)) == SEM_FAILED) {
perror("semaphore initilization");
exit(1);
}
sem_unlink(sname);
sem_close(pSemaphor);
}
When I run it under valgrind, I get the following error:
==12702== Syscall param write(buf) points to uninitialised byte(s)
==12702== at 0x4E457A0: __write_nocancel (syscall-template.S:81)
==12702== by 0x4E446FC: sem_open (sem_open.c:245)
==12702== by 0x4007D0: main (test.cpp:15)
==12702== Address 0xfff00023c is on thread 1's stack
==12702== in frame #1, created by sem_open (sem_open.c:139)
The code was extracted from a bigger project where it ran successfully for years, but now it is causing segmentation fault.
The valgrind error from my example is the same as seen in the bigger project, but there it causes a crash, which my small example doesn't.
I see this with glibc 2.27-5 on Debian. In my case I only open the semaphores right at the start of a long-running program and it seems harmless so far - just annoying.
Looking at the code for sem_open.c which is available at:
https://code.woboq.org/userspace/glibc/nptl/sem_open.c.html
It seems that valgrind is complaining about the line (270 as I look now):
if (TEMP_FAILURE_RETRY (__libc_write (fd, &sem.initsem, sizeof (sem_t)))
== sizeof (sem_t)
However sem.initsem is properly initialised earlier in a fairly baroque manner, firstly by explicitly setting fields in the sem.newsem (part of the union), and then once that is done by a call to memset (L226-228):
/* Initialize the remaining bytes as well. */
memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0',
sizeof (sem_t) - sizeof (struct new_sem));
I think that this particular shenanigans is all quite optimal, but we need to make sure that all of the fields of new_sem have actually been initialised... we find the definition in https://code.woboq.org/userspace/glibc/sysdeps/nptl/internaltypes.h.html and it is this wonderful creation:
struct new_sem
{
#if __HAVE_64B_ATOMICS
/* The data field holds both value (in the least-significant 32 bytes) and
nwaiters. */
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define SEM_VALUE_OFFSET 0
# elif __BYTE_ORDER == __BIG_ENDIAN
# define SEM_VALUE_OFFSET 1
# else
# error Unsupported byte order.
# endif
# define SEM_NWAITERS_SHIFT 32
# define SEM_VALUE_MASK (~(unsigned int)0)
uint64_t data;
int private;
int pad;
#else
# define SEM_VALUE_SHIFT 1
# define SEM_NWAITERS_MASK ((unsigned int)1)
unsigned int value;
int private;
int pad;
unsigned int nwaiters;
#endif
};
So if we __HAVE_64B_ATOMICS then the structure has a data field which contains both the value and the nwaiters, otherwise these are separate fields.
In the initialisation of sem.newsem we can see that these are initialised correctly, as follows:
#if __HAVE_64B_ATOMICS
sem.newsem.data = value;
#else
sem.newsem.value = value << SEM_VALUE_SHIFT;
sem.newsem.nwaiters = 0;
#endif
/* pad is used as a mutex on pre-v9 sparc and ignored otherwise. */
sem.newsem.pad = 0;
/* This always is a shared semaphore. */
sem.newsem.private = FUTEX_SHARED;
I'm doing all of this on a 64-bit system, so I think that valgrind is complaining about the initialisation of the 64-bit sem.newsem.data with a 32-bit value since from:
value = va_arg (ap, unsigned int);
We can see that value is defined simply as an unsigned int which will usually still be 32 bits even on a 64-bit system (see What should be the sizeof(int) on a 64-bit machine?), but that should just be an implicit cast to 64-bits when it is assigned.
So I think this is not a bug - just valgrind getting confused.
Okay, so I'm trying to work on this hangman program, and when I check it with valgrind i keep getting Conditional jump or move depends on uninitialized value(s) with my strcpy and
Here is the header source file:
#include "randword.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static char **list;
void InitDictionary(char* name){
int size=0, ln;
FILE *fp = fopen(name, "r");
list = (char**)malloc(50*sizeof(char*));
*list = (char*)malloc(50*sizeof(char));
while(fgets(*(list+size), 49, fp)){
for(ln=0;*(*(list+size)+ln)!='\0';ln++){}
ln=ln-1;
if (*(*(list+size)+ln) == '\n')
*(*(list+size)+ln) = '\0';
size++;
*(list+size) = (char*)malloc(50*sizeof(char));
}
fclose(fp);
}
void ChooseRandomWord(char** word){
int randIndex,num;
for(num=0;*(list+num)!=NULL;num++){}
srand(time(NULL));
randIndex = rand() % (num-1);
strcpy(*word, *(list+randIndex));
for(;num>=0;num--)
free(*(list+num));
free(list);
}
and here is the main file itself:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "randword.h"
int main(){
char *word, *reveal, guess;
int guesses = 8,i,x,index,correct=0,istrue;
reveal = (char*)malloc(50*sizeof(char));
word = (char*)malloc(50*sizeof(char));
InitDictionary("words.txt");
ChooseRandomWord(&word);
for(x=0;*(word+x)!='\0';x++){
*(reveal+x)='-';
}
printf("Welcome to Hangman!\nI will guess a secret word. On each turn, you guess\na letter. If the letter is in the secret word, I\nwill show you where it appears; if not, a part of\nyour body gets strung up on the scaffold. The\nobject is to guess the word before you are hung.\n");
while(guesses>0){
istrue=0;
printf("Your word now looks like this: %s\nYou have %d guesses left.\n", reveal, guesses);
printf("Guess a letter: ");
scanf("%c", &guess);
getchar();
guess = toupper(guess);
for(index=0;*(word+index)!='\0';index++){
if(*(word+index)==guess){
if(*(word+index)==*(reveal+index)){
istrue=2;
break;
}
else{
istrue=1;
*(reveal+index)=*(word+index);
correct++;
}
}
}
if(istrue==2){
printf("You have already guessed %c.\n",guess);
}
else if(istrue){
printf("That is correct.\n");
}
else{
printf("There are no %c's in the word.\n", guess);
guesses--;
}
if(*(word+correct)=='\0'){
printf("You guessed the word: %s.\n", reveal);
free(reveal);
free(word);
return 0;
}
}
printf("You have run out of guesses and lost.\n");
free(word);
free(reveal);
return 0;
}
here is the valgrind output:
==5319== Conditional jump or move depends on uninitialised value(s)
==5319== at 0x80487F1: ChooseRandomWord (in /home/ulr146/GOZA_hw4/randword)
==5319== by 0x80488CB: main (in /home/ulr146/GOZA_hw4/randword)
==5319== Uninitialised value was created by a heap allocation
==5319== at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==5319== by 0x80486E3: InitDictionary (in /home/ulr146/GOZA_hw4/randword)
==5319== by 0x80488C0: main (in /home/ulr146/GOZA_hw4/randword)
==5319==
==5319== Conditional jump or move depends on uninitialised value(s)
==5319== at 0x4025DBD: free (vg_replace_malloc.c:323)
==5319== by 0x804885E: ChooseRandomWord (in /home/ulr146/GOZA_hw4/randword)
==5319== by 0x80488CB: main (in /home/ulr146/GOZA_hw4/randword)
==5319== Uninitialised value was created by a heap allocation
==5319== at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==5319== by 0x80486E3: InitDictionary (in /home/ulr146/GOZA_hw4/randword)
==5319== by 0x80488C0: main (in /home/ulr146/GOZA_hw4/randword)
Welcome to Hangman!
I will guess a secret word. On each turn, you guess
a letter. If the letter is in the secret word, I
will show you where it appears; if not, a part of
your body gets strung up on the scaffold. The
object is to guess the word before you are hung.
==5319==
==5319== Conditional jump or move depends on uninitialised value(s)
==5319== at 0x40276F7: strlen (mc_replace_strmem.c:242)
==5319== by 0x406F6D7: vfprintf (vfprintf.c:1581)
==5319== by 0x4075B5F: printf (printf.c:35)
==5319== by 0x8048923: main (in /home/ulr146/GOZA_hw4/randword)
==5319== Uninitialised value was created by a heap allocation
==5319== at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==5319== by 0x80488A2: main (in /home/ulr146/GOZA_hw4/randword)
Your word now looks like this: ----
You have 8 guesses left.
Guess a letter: d
That is correct.
Your word now looks like this: D---
You have 8 guesses left.
Guess a letter: a
That is correct.
Your word now looks like this: DA-A
You have 8 guesses left.
Guess a letter: t
That is correct.
==5319==
==5319== Conditional jump or move depends on uninitialised value(s)
==5319== at 0x40276F7: strlen (mc_replace_strmem.c:242)
==5319== by 0x406F6D7: vfprintf (vfprintf.c:1581)
==5319== by 0x4075B5F: printf (printf.c:35)
==5319== by 0x8048A3E: main (in /home/ulr146/GOZA_hw4/randword)
==5319== Uninitialised value was created by a heap allocation
==5319== at 0x4026FDE: malloc (vg_replace_malloc.c:207)
==5319== by 0x80488A2: main (in /home/ulr146/GOZA_hw4/randword)
You guessed the word: DATA.
==5319==
==5319== ERROR SUMMARY: 6 errors from 4 contexts (suppressed: 13 from 1)
==5319== malloc/free: in use at exit: 0 bytes in 0 blocks.
==5319== malloc/free: 10 allocs, 10 frees, 952 bytes allocated.
==5319== For counts of detected errors, rerun with: -v
==5319== All heap blocks were freed -- no leaks are possible.
I can't quite figure out how to fix the uninitialized value issues because I don't know what I did that made it uninitialized.
You allocated one more element for list than the items read from file in InitDictionary(). Thus, when you going toward the last non-NULL pointer in list in ChooseRandom(), it tried to go toward the end of an uninitialized array.
IMHO, I would set up list as follows:
int size = 0;
char buf[50];
list = malloc(50*sizeof(char*));
while(fgets(buf, 49, fp)){
list[size] = malloc(50 * sizeof(char));
for(ln=0;buf[ln]!='\0';ln++){
list[size][ln] = buf[ln];
}
list[size][ln] = '\0';
--ln;
if (list[size][ln] == '\n')
list[size][ln] = '\0';
size++;
}
That is, use a local array for reading. Allocate for new array only after a new line is read.
I need to take a char [] array and copy it's value to another, but I fail every time.
It works using this format:
char array[] = { 0x00, 0x00, 0x00 }
However, when I try to do this:
char array[] = char new_array[];
it fails, even though the new_array is just like the original.
Any help would be kindly appreciated.
Thanks
To copy at runtime, the usual C method is to use the strncpy or memcpy functions.
If you want two char arrays initialized to the same constant initializer at compile time, you're probably stuck with using #define:
#define ARRAY_INIT { 0x00, 0x00, 0x00 }
char array[] = ARRAY_INIT;
char new_array[] = ARRAY_INIT;
Thing is, this is rarely done because there's usually a better implementation.
EDIT: Okay, so you want to copy arrays at runtime. This is done with memcpy, part of <string.h> (of all places).
If I'm reading you right, you have initial conditions like so:
char array[] = { 0x00, 0x00, 0x00 };
char new_array[] = { 0x01, 0x00, 0xFF };
Then you do something, changing the arrays' contents, and after it's done, you want to set array to match new_array. That's just this:
memcpy(new_array, array, sizeof(array));
/* ^ ^ ^
| | +--- size in bytes
| +-------------- source array
+-------------------------destination array
*/
The library writers chose to order the arguments with the destination first because that's the same order as in assignment: destination = source.
There is no language-level built-in means to copy arrays in C, Objective-C, or C++ with primitive arrays like this. C++ encourages people to use std::vector, and Objective-C encourages the use of NSArray.
I'm still not sure of exactly what you want, though.