VxWorks Interpreter - Creating structs - c

I'm new to development in VxWorks (using 6.8) and I've run into a situation where I need to pass the address of a struct to a function. Is it possible to create a struct from the interpreter shell? I have a hard copy of a VxWorks programmers guide that is based on v5.5 and it explicitly says that structs cannot be formed/created from the interpreter shell. Has this changed in later versions of VxWorks and if so, how would I make a struct from the command line.
As a VxWorks newb, I was hoping to run the command
myStruct = {msg1 ="hi", msg2 = "hello" }
and then use the struct in another statement like
printf("%s\n", myStruct.msg1)
If a struct cannot be created in the interpreter like above, what options can I pursue in order to get the printf statement to print "hi" or "hello" by accessing a member within the struct?

No, as of 6.9 the vxWorks C shell does not support structs. See the C Interpreter Limitations section of the Wind River Workbench Host Shell User's Guide. The shell uses a symbol table that does not track the types of its symbols, and you cannot define types on the command line.
To get the same behavior, you could allocate memory for a struct and then fill it in by address. The size you allocate doesn't have to be exact, but your memory offsets do. Your example is easy because you have only 2 pointers, and your struct wouldn't have any padding. If you are on a 32-bit processor, then the size of a pointer is 4 bytes. So the first pointer is at offset 0, 1, 2, and 3, and then the 2nd pointer starts at offset 4.
E.g.,
-> mystruct = malloc(50);
New symbol "mystruct" added to kernel symbol table.
mystruct = 0x3a320a0: value = 63949520 = 0x3cfcad0
-> mystruct[0] = "hi";
0x3cfcad0: value = 61030776 = 0x3a364a0
-> mystruct[4] = "hello";
0x3cfcae0: value 61040928 = 0x3a36920 = ' '
-> printf("%s\n", mystruct[4]);
hello
value = 6 = 0x6
Things would get tricky as your struct got larger, and if there were padding. E.g., struct { char, int } could have a size of 6 or 8 depending on your processor's alignment requirements, so you'd have to be aware of that when trying to get the offset of the int. If it got too complicated, you could compile helper functions in your code that perhaps look like this pseudo code:
struct st { char a; int b; char *c; };
struct st *make_me_a_struct(char a, int b, char *c)
{
struct st *newstruct = malloc(sizeof(st));
newstruct->a = a;
newstruct->b = b;
newstruct->c = c;
return newstruct;
}

Related

Strange behaviour in C program, variable corruption after allocating memory

I have typdef of string in my C program, it looks like that:
#define WRD_LEN 100
typedef char cstring[WRD_LEN];
then at some point I declare dynamic array of this type:
int pcount = 1;
cstring *options = malloc(sizeof(cstring*)*pcount);
I add new strings to this array with use of realloc:
options = realloc(options, sizeof(cstring*)*pcount);
strcpy(options[pcount-1], //some string//);
pcount++;
and then show all entries to user, user choses one of them and that one is passed to another function:
highestof(mode, l, options[btn]);
mode is an integer, l is struct but those are irrelevant now. btn is number (int) of entry chosed by user.
Up to this point everything works just fine, problem shows up inside highestof function:
void highestof(const int mode, List l, const cstring cat) {
List *p = malloc(sizeof(List*));
here is definition of List:
struct W {
//some data
struct W *next;
};
struct List {
struct W *first;
};
So if highestof function is called with options[1], cat variable will get corrupted (it will became a set of few random symbols, like "#^?" or "^K^?") right after malloc is called i.e. before creating dynamic array of List I can use cat as much as I want, but after calling malloc it gets corrupted. Most strange thing about this is that it happens only if variable passed down to this function was in options array under index of 1 (options[btn] where btn = 1) For any other value of btn it works no problem.
I found a workaround for this, I can create a string (char s[100]) before calling malloc, copy cat value into it and use that variable instead, but it's really not resolving initial problem and it really bothers me.
sizeof(cstring*)*pcount is too small. The size calculation is amiss.
Avoid allocation errors. Use this idiom for code that is easier to write correctly, review and maintain.
Notice no type is used.
pointer = malloc(sizeof *pointer * n);
Then code becomes:
// options = malloc(sizeof(cstring*)*pcount);
options = malloc(sizeof *options * pcount);`
cstring* is just a pointer, usually four or eight bytes. sizeof (cstring*) is therefore a small number, usually four or eight.
You are not allocating enough memory for the data, just enough memory to hold pointers to the data.

Structure and array declaration on same memory location

I am working on one Embedded C project. I am having trouble understanding the use of array and structure in code.
for example:
Structure:
struct example_struct{
char a;
char b;
char array[4];
}
Note: The default size for Int and char is 1 byte.
The compiler I am using provide the functionality of memory allocation for variables and other parameters using '#' symbol
for example:
Memory Allocation
int example # 0x125
// Compiler allocate the RAM memory location 0x125 to my variable "example"
Issue:
The person who coded this project have used the structure and array as given below
example.h
struct example_struct{
char a;
char b;
char array[4];
}
Memory.h
volatile struct example_struct node # 0x130 ;
//allocate memory location 0x130 - 0x135 to node
volatile char buffer[6] # 0x130;
//allocate memory location 0x130 - 0x135 to buffer
Question
1.Instead of using the pointer to access the member of structure is it appropriate to use the array placed on same memory location?
Does it cause the memory issue?
Would you please help me to understand the use of stuct and array in this particular situation.
Thank you
Kunal
The (weird) coder that developed that code was "simulating" an union to be able to access the same location as struct example_struct or byte per byte.
Like:
#pragma pack(1)
union struct_and_raw_byte_access
{
struct example_struct
{
char a;
char b;
char array[4];
}structured;
char buffer[sizeof(struct example_struct)];
};
#pragma pack()
int main(void)
{
union struct_ad_raw_byte_access temp;
int i;
temp.structured.a = 1;
temp.structured.b = 2;
temp.structured.array[0] = 3;
temp.structured.array[1] = 4;
temp.structured.array[2] = 5;
temp.structured.array[3] = 6;
for (i=0; i< sizeof(temp.buffer)/sizeof(temp.buffer[0]); i++)
printf("buffer[%d] = %d\n", i, temp.buffer[i]);
return 0;
}
1.Instead of using the pointer to access the member of structure is it appropriate to use the array placed on same memory location?
2.Does it cause the memory issue?
IMHO you cannot do that. It may work in some archs, but keep in mind that you are trusting the compiler to put everything packed and aligned.
Some compilers have packing directives (pragmas or parameteres), but it is much more safer to use an union.
Make sure that buffer is also a pointer, so allocating "buffer" to absolute address is the same like make a pointer to that address.
volatile char buffer[6] # 0x130;
//allocate memory location 0x130 - 0x135 to buffer
In your case, developer; I think; he decided to access strcutre elements using array for work with them in loop or something.
So, answering your questions:
No, It is not appropriate, as you said, it is better to make pointer and access this pointer by casting it to (char *)
If you know how you will use "buffer", no memory issue will happen. I mean make sure no out of index will happen.
Your comment "if I am declaring any global variable and watching it using debugger I can see the change in value. Even if I am not using them anywhere" probably means that you are looking at a hardware register of some IO controller.
The
volatile char buffer[6] # 0x130;
Is intended to map those IO controller addresses to a variable name in your embedded programming. That is the IO controller is presenting status and data at memory address 0x130 to 0x135 -- and the C program maps this to a symbolic value through the declaration.
Since the format of this area is determined by the IO controller (nothing you can do in your C code will change the format), you need to make sure that the strct and the example_struct is exactly 6 bytes long, or if not you have some padding which will kill you.
Test this using your debugger (if it is gdb use can use sizeof, but your debugger may differ)
Also, I recommend that you find some kind of documentation on what is on hardware address 0x130

How do I set values inside a global, fixed-size array, in C (in Visual Studio)?

A part of my VS2012 Windows Phone project is in C. I've been struggling during one day trying to initialize an array to put stuff inside it.
Whenever I try to initialize it as global (outside any function), then I get a message telling me that I can't initialize it with a value that isn't a const.
const char* myArray = (const char*)malloc(256);
// Bad code: this isn't initialized with a const
If I don't initialize it with a value, then I'll have a message telling me to give it a value. So I assign a NULL value to the array.
const char* myArray = NULL;
Then I need to set a size somewhere, so I set the size within my main, or first function:
int myFirstFunctionInTheCode()
{
myArray = (char*)malloc(256);
}
Then I get something like:
';' expected before type
So I'm searching on forum and read that C in Visual Studio is C89, thus, I need to declare then to assign on two separate line, which isn't true elsewhere in my code, so I'm completely mixed-up about -real- standards. But I still get the same error when doing it on two lines.
I then decide to use some other tools from the available VS libraries to find out that in C, I can't include sstream, streambuf, etc, otherwise my whole project fails with thousands of bugs. So I could use boost to get a real stream libraries, but it's not compatible with Windows Phone because of some thread usage.
How do I set values inside a global, fixed-size array, in C (in Visual Studio)?
What I want to achieve is similar to something in C# like it:
static byte[] gentleCSharpArray = new byte[256];
private void easyShotCSharpFunction()
{
gentleCSharpArray[0] = 0x57;
gentleCSharpArray[1] = 0x54;
gentleCSharpArray[2] = 0x46;
}
I never spent so much time trying to assign a value to an array, so I guess I'm totally wrong with my global char* arrays?
PART ONE
const char* myArray = (const char*)malloc(256);
This doesn't work because global variables in C are divvied into two spaces: the data segment and the bss segment. For example:
#include <stdio.h>
#include <stdlib.h>
int* myArray; // uninitialized, represented by bss segment
const char* myArray2 = "abc"; // initialized, goes into data segment
int main ()
{
myArray = malloc(3*sizeof(int));
myArray[0] = 111;
myArray[1] = 222;
myArray[2] = 333;
int i;
for (i=0; i<3; i++)
printf("%d, %c\n", myArray[i], myArray2[i]);
return 0;
}
When this is compiled, the const char* myArray2 = "abc"; does not translate into machine instructions. Instead, an image of what "abc" looks like in memory is created and put into the data segment, along with every other initialized global variable. Later, the program loader picks up that entire data segment and sticks it in memory, before your program even starts to run.
Uninitialized variables, like myArray in the example, don't even have that much happen. Rather, it is represented in the BSS segment as the compiler says, "we're going to need n bytes of memory reserved for uninitialized variables." Later, the program loader takes note of this and reserves those n bytes, before your program even starts to run.
Thus, it doesn't make sense to try and malloc when you initialize global variables, because when the globals are created your program isn't running yet. The machine instructions for malloc may not even be in memory yet!
PART TWO
static byte[] gentleCSharpArray = new byte[256];
private void easyShotCSharpFunction()
{
gentleCSharpArray[0] = 0x57;
gentleCSharpArray[1] = 0x54;
gentleCSharpArray[2] = 0x46;
}
Okay, let's translate this bit by bit from C# to C. Are you using const in C because constant and static are (almost) synonyms in standard English? Because they're very different in programming.
The keyword const in C and C# means that the variable cannot be an L-value.
The keyword static in object-oriented languages (like C#) means that a function or variable is unchanging with respect to the object instance of its class. C has no objects and thus no analog.
The keyword static is used in plain C to mean that a variable is unchanging with respect to its invocation, or a function is unchanging with respect to where it can be seen (similar to private in C#, you can read more here).
But what are you really wanting to do there? Just reserve a huge chunk of memory for the program, right? C has no byte data type, but char is one byte in size; you can use that instead. The unsigned keyword makes it clear to program inspectors that this will not be used for a string:
// Compiled and ran with gcc -O0 -g -Wall on Ubuntu
#include <stdio.h>
#include <stdlib.h>
int* myArray;
const char* myArray2 = "abc";
unsigned char gentleCArray[256]; // <-- here's the declaration you want
static void easyShotCFunction()
{
gentleCArray[0] = 0x57;
gentleCArray[1] = 0x54;
gentleCArray[2] = 0x46;
}
int main ()
{
myArray = malloc(3*sizeof(int));
myArray[0] = 111;
myArray[1] = 222;
myArray[2] = 333;
easyShotCFunction();
int i;
for (i=0; i<3; i++)
printf("%d, %c, 0x%x\n", myArray[i], myArray2[i], gentleCArray[i]);
return 0;
}
When the program starts, gentleCArray will already be a pointer to 256 bytes of memory, most likely all zeroes. This is a consequence of the BSS segment I mentioned in part 1. Useful for doing your own memory management without malloc.
You either:
const char my_array[] = "abcdef";
or:
char *my_array;
int main(void)
{
my_array = malloc(some_size);
/* initialize elements of my_array */
}
Example 1 makes no sense because you are attempting to initialize a static variable at runtime.
Example 2 makes no sense because you are attempting to modify a const object. Essentially, you did the opposite of what could work in either situation.
What I want to achieve is similar to something in C# like it:
static byte[] gentleCSharpArray = new byte[256];
private void easyShotCSharpFunction()
{
gentleCSharpArray[0] = 0x57;
gentleCSharpArray[1] = 0x54;
gentleCSharpArray[2] = 0x46;
}
Ok, then you want;
unsigned char arr[256];
void c_version(void)
{
arr[0] = 0x57;
arr[1] = 0x54;
arr[2] = 0x46;
}

Struct argument passed in pthread create gets mangled

I have a structure named command that looks like this. The first value in the enum is AND_COMMAND
struct command
{
enum command_type type;
int status;
char *input;
char *output;
union
{
struct command *command[2];
char **word;
struct command *subshell_command;
} u;
};
When I call pthread_create I pass it a command in the form of a command_t (that is cast to (void *)).
typedef struct command *command_t;
My thread takes this (void *) command_t, casts it back (command_t) and tries to use the structure.
void execute_thread(void *c) {
command_t command = (command_t) c;
However when I pass a struct in to execute_thread the first values are zeroed out. If I have a command_type of SIMPLE_COMMAND and status of -1, when it's passed in to the thread the command_type is AND_COMMAND and status of 0. None of the other values in the struct are changed however. What's more curious is when this data mangling occurs. I was able to capture the phenomenon in gdb:
445 command_t command = (command_t) c;
(gdb) p *((command_t) c)
$6 = {type = SIMPLE_COMMAND, status = -1, input = 0x605370 "abc", output = 0x605390 "def", u = {
command = {0x6052e0, 0x0}, word = 0x6052e0, subshell_command = 0x6052e0}}
(gdb) n
(gdb) p *((command_t) c)
$7 = {type = AND_COMMAND, status = 0, input = 0x605370 "abc", output = 0x605390 "def", u = {command = {
0x6052e0, 0x0}, word = 0x6052e0, subshell_command = 0x6052e0}}
It appears that the structure pointed to by c doesn't change until casting it with (command_t) c; I am entirely confounded by this behavior. I didn't think that casting a pointer could change the values it pointed to. Could someone please point out, ha ha, what could be going on here? I would appreciate that very much.
What's more curious is when this data mangling occurs. I was able to capture the phenomenon in gdb:
The wording here leads me to believe that the problem isn't deterministic; ie., sometimes it doesn't happen, or it doesn't happen at the moment you happened to capture in gdb in the question.
If that's the case (and maybe even if it isn't), I suspect that you problem is that you're trashing the memory allocated to the struct command in the main thread (or whatever thread is creating the execute_thread() thread). You didn't show us the thread creation code, but if you use a local variable and pass the address of that to the created thread, then it can be tricky to make sure the local variable's lifetime doesn't expire before the the second thread gets around to using it. You might want to pass in a struct command that has been allocated on the heap:
struct command* thread_data = malloc(sizeof(struct command));
struct_command_init(thread_data);
pthread_create(/* ... */, thread_data);
// ...
and in the execute_command() thread:
void* execute_command(void* p)
{
struct command cmd = *(struct command*)p;
free(p);
// use cmd to get at the structure data passed in...
}
Keep in mind that the data referred to by various pointers insode the struct command also need to have their lifetime and ownership clearly managed, too.

Unexpected C struct pointer size behaviour

I have some odd behaviour going on in my code which seems to be resulting from the use of a generic pointer though really I am totally uncertain. I have a fairly standard struct which looks like the following:
typedef struct {
char* name;
PyAutoCFunc ac_func;
void (*func)();
PyAutoType type_id;
int num_args;
PyAutoType arg_types[MAX_ARG_NUM];
} func_entry;
static func_entry* func_entries;
I am storing a static pointer to an array of these struct elements which is allocated on the heap. At the point where I create a new element of this array and insert it, its values look like this...
func_entry new_fe;
new_fe.name = malloc(strlen(name) + 1);
strcpy(new_fe.name, name);
... // Init rest of struct
func_entries[num_func_entries] = new_fe;
num_func_entries++;
func_entry* fe = &func_entries[num_func_entries-1];
printf("Setting function '%s' at address '%p', name address '%p'\n", name, fe, fe->name);
This outputs.
>>> Setting function 'graphics_viewport_set_title' at address '0xfe2d40', name address '0xe40fe0'
Notice the size and value of fe->name. I then store this pointer into a hashtable to retrieve later. In the hashtable this is stored as a simple void*. Later when I retrieve the pointer from the hashtable an odd thing happens.
func_entry* fe = PyAutoHashtable_Get(func_table, c_func_name);
printf("Getting function '%s' at address '%p', name address '%p'\n", c_func_name, fe, fe->name);
Which outputs.
>>> Getting function 'graphics_viewport_set_title' at address '0xfe2d40', name address '0x6e6f74656c656b73'
The address of fe has clearly been in and out of the hashtable without issue, but the size and address of fe->name has changed. Even more weirdly is that fe->name is a different size to what it was before and even a different size to fe. Trying to access fe->name gives me a segfault and I am unsure how to proceed.
Out of interest this seems to occur when I use the code in an application with several linked libraries, I'm fairly sure all the code I'm running is 64 bit.
I have run the above code successfully in a separate application and get a correct pointer for fe->name (a smaller one).
I am also running on Ubuntu Linux 64 bit and compiling with gcc.
This is really where my C ignorance shines though as I imagine it could be a million things. Can anyone shine some light?
That address for name looks like the result of memory corruption. It's completely unaligned, which is unlikely for an address returned by strdup off the heap.
It looks like you're out of scope for the structure you created. You mentioned it's created on the heap, but in the code it looks like it's probably created on the stack. This isn't all being done in the same function, is it? Is the code in the first block in a function that's existed before running the code in the later block? As soon as you exit that function the memory for that structure ceased to be, even though you retained a pointer to it. Later, when you pulled the pointer out of the hash table the memory had been overwritten and didn't have the pointer to name there anymore. If you're going to pass around pointers to structures allocate them dynamically by using malloc. They're exist until you explicitly get rid of them using free, instead of when the function ends.
Pointers always are of the same size whether its a pointer to a struct or a generic pointer (char * in olden days, void * in ANSI standard.)
Here's a simple example I whipped out so that you could understand structures, pointers (not in detail though but you get the idea.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person {
char *name;
int age;
};
void print(void *);
int main()
{
struct person *david;
if ((david = (struct person *)malloc(sizeof(struct person))) != NULL) {
david->name = strdup("David");
david->age = 40;
printf("sizeof david = %d, sizeof person = %d\n", sizeof david,
sizeof(struct person));
print((void *)david);
}
}
void print(void *p)
{
struct person *pp = (struct person *)p;
printf("sizeof p = %d, sizeof pp = %d\n%s %d\n", sizeof p, sizeof pp,
pp->name, pp->age);
}
Output
sizeof david = 8, sizeof person = 16
sizeof p = 8, sizeof pp = 8
David 40
Hope that helps.
It certainly looks as if something is writing over that data structure. The pointer value 0x6e6f74656c656b73 which you are seeing looks very suspicious indeed - it is ASCII for "noteleks", which is "skeleton" backwards. Perhaps this might give you an idea of what is overwriting your data.

Resources