VxWorks 5.5 not filling stack with 0xEEEEEEEE - c

From taskSpawn VxWorks 5.5 documentation :
"The only resource allocated to a spawned task is a stack of a specified size stackSize, which is allocated from the system memory partition. Stack size should be an even integer. A task control block (TCB) is carved from the stack, as well as any memory required by the task name. The remaining memory is the task's stack and every byte is filled with the value 0xEE for the checkStack( ) facility. See the manual entry for checkStack( ) for stack-size checking aids. "
However when tried to scan the stack by spawning a brand new task:
int scan_the_stack(...)
{
printf("Going to scan the stack forward\n");
int i = 0;
int* stack_addr = &i;
for (int i = 0; i < 100; i++)
{
printf("%d : %X\n", i, *stack_addr);
stack_addr++;
}
return 0;
}
void spawn_scan_stack()
{
taskSpawn("tScanner", /* name of new task (stored at pStackBase) */
150, /* priority of new task */
VX_FP_TASK, /* task option word */
10000, /* size (bytes) of stack needed plus name */
scan_the_stack, /* entry point of new task */
0, /* 1st of 10 req'd args to pass to entryPt */
0,0,0,0,0,0,0,0,0);
}
Instead of getting expected consecutive 'EEEEEEEE' I got some 'EE' intermixed with other values:
-> spawn_scan_stack
value = 80735920 = 0x4cfeeb0
-> Going to scan the stack forward
0 : 0
1 : 4CFEE1C
2 : 2
3 : EEEEEEEE
4 : EEEEEEEE
5 : EEEEEEEE
6 : EEEEEEEE
7 : 0
8 : 0
9 : 0
10 : 4CFEE70
11 : 2951F4
12 : 0
13 : 0
14 : EEEEEEEE
15 : EEEEEEEE
16 : EEEEEEEE
17 : EEEEEEEE
18 : EEEEEEEE
19 : 0
20 : 0
21 : 0
22 : 0
23 : 0
24 : EEEEEEEE
25 : EEEEEEEE
26 : EEEEEEEE
27 : EEEEEEEE
28 : 0
29 : 0
30 : 0
31 : 0
32 : 0
33 : 0
34 : 0
35 : 0
36 : 0
37 : 0
38 : 0
39 : 0
40 : 96
41 : FF630
42 : 20
43 : 11000001
44 : 19BDD /*...*/
The question is why isn't the stack filled with EEEEEEE (also checkStack seems to be working still).

Try 'stack_addr--;' - bet you're on Intel where the stacks grow downwards. You are looking up at valid stack data - return addresses and local vars, some of which are uninitialised.

My initial assumption was that the task had been spawned with VX_NO_STACK_FILL, which tells vxworks not to initialise the stack to 0xEE. But, looking at your code, you just use VX_FP_TASK (for floating point support). So the stack should be correctly initialised.
That really leaves two possibilities. The first (and more unlikely) is that something else is writing where it shouldn't be, but you would likely be seeing strange behaviour elsewhere (and i might expect checkStack to show that something has been smashed)
The second, as already suggested by others is that you are on one of the architectures (such as intel) where the stack grows downwards. The VxWorks Architecture Supplement should tell you which direction the stack grows for your architecture.
You might also be able to tell at compile time by including vxArch.h and testing the value of _STACK_DIR for _STACK_GROWS_DOWN or _STACK_GROWS_UP

Related

Map Var to Declaration Using Dwarf DebugInfo and Source Code

Given the line number of a variable access (not declaration), how can I determine its type (or its declaration DIE in the .info tree)?
Look at the following code:
void foo()
{
{
struct A *b;
}
{
struct B *b;
b = malloc(sizeof(struct B));
}
}
Suppose that I have this source code and it is compiled with debug information in DWARF format. How can I determine that variable b is of type struct B * using the source code and debug information?
I mean how can I automatize it offline? The problem is that in the .info section of DWARF there is no mapping between source code (e.g., line number) and scope information. In the example above, using debug information, we can determine that there is a variable of type struct A * which is a child of foo() and a variable of type struct B * which is the other child of foo(). Parsing the source code can help to determine the nesting level at which the access has occurred, but there is no way to map the accessed variable to its type. Because there are two types at the same level at which b is accessed.
If there is a way to force the compiler to include more information in the debug information, the problem can be solved. For example, adding DW_AT_high_pc and DW_AT_low_pc to the debug information of DIEs of type DW_TAG_lexical_block will help.
You have already answered almost all of your own question; there are only two things missing.
Firstly, the relationship between file name/line number and program counter is encoded in .debug_line, not .debug_info.
Secondly, the variables are not children of foo(): each is a child of a lexical block. The relevant portion of the program structure will look like
DW_TAG_compile_unit
DW_TAG_subprogram
DW_TAG_lexical_block
DW_TAG_variable
DW_TAG_lexical_block
DW_TAG_variable
The lexical block should be associated with an address range but this might be encoded using DW_AT_ranges instead of DW_AT_low_pc/DW_AT_high_pc; if that's the case then you'll need to interpret .debug_ranges.
To illustrate the case in hand I compiled the following with cc -g (gcc 4.8.5 on Oracle Linux)...
1 #include <stdlib.h>
2
3 struct A { int a; };
4 struct B { int b; };
5
6 void foo()
7 {
8 {
9 struct A *b;
10 }
11
12 {
13 struct B *b;
14 b = malloc(sizeof (struct B));
15 }
16 }
...and used 'readelf -w' to decode the DWARF. Line 14 appears here in the line number table:
[0x00000032] Special opcode 124: advance Address by 8 to 0x8 and Line by 7 to 14
meaning that we're interested in address 0x8. The DIE hierarchy includes
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
<1><96>: Abbrev Number: 6 (DW_TAG_subprogram)
<9d> DW_AT_low_pc : 0x0
<a5> DW_AT_high_pc : 0x18
<2><b3>: Abbrev Number: 7 (DW_TAG_lexical_block)
<b4> DW_AT_low_pc : 0x8
<bc> DW_AT_high_pc : 0xe
<3><c4>: Abbrev Number: 8 (DW_TAG_variable)
<c5> DW_AT_name : b
<c7> DW_AT_decl_file : 1
<c8> DW_AT_decl_line : 13
<c9> DW_AT_type : <0xd2>
The DIE at 0xb3 does not contain any further lexical blocks so it represents the tightest scope at address 0x8. At this point, hence, the name "b" must refer to the DIE's child at 0xc4. This variable's type is given by
<1><d2>: Abbrev Number: 9 (DW_TAG_pointer_type)
<d3> DW_AT_byte_size : 8
<d4> DW_AT_type : <0x81>
<1><81>: Abbrev Number: 4 (DW_TAG_structure_type)
<82> DW_AT_name : B
<84> DW_AT_byte_size : 4
<2><8b>: Abbrev Number: 5 (DW_TAG_member)
<8c> DW_AT_name : b
<90> DW_AT_type : <0x34>
<94> DW_AT_data_member_location: 0
<1><34>: Abbrev Number: 3 (DW_TAG_base_type)
<35> DW_AT_byte_size : 4
<36> DW_AT_encoding : 5 (signed)
<37> DW_AT_name : int
EDIT:
In your own answer you've given a counter-example for mplayer in which there are lexical blocks without corresponding address ranges. Such DWARF does not conform to the standard: §3.4 of DWARF 2 states that a lexical block entry has DW_AT_low_pc and DW_AT_high_pc attributes and makes no suggestion that these are optional. A likely candidate for this bug, assuming you're using gcc, is "DWARF debug info for inlined lexical blocks missing range". The default mplayer configuration includes -O2 optimisation, which turns on inlining; you will see this reflected in the parent DW_TAG_subprogram for draw_vertices(), from which the example code is taken. A workaround for the bug is to add -fno-inline to the compiler options; this does not seem to suppress all inlining so you may wish to disable optimisation altogether.
Here is the output of objdump --dwarf=info mplayer for an MPlayer-1.3.0 compiled using -gdwarf-2 option.
<2><4000e>: Abbrev Number: 43 (DW_TAG_lexical_block)
<3><4000f>: Abbrev Number: 37 (DW_TAG_variable)
<40010> DW_AT_name : px
<40013> DW_AT_decl_file : 1
<40014> DW_AT_decl_line : 2079
<40016> DW_AT_type : <0x38aed>
<3><4001a>: Abbrev Number: 37 (DW_TAG_variable)
<4001b> DW_AT_name : py
<4001e> DW_AT_decl_file : 1
<4001f> DW_AT_decl_line : 2080
<40021> DW_AT_type : <0x38aed>
<3><40025>: Abbrev Number: 0
<2><40026>: Abbrev Number: 0
As you can see at offset 0x4000e, there is a lexical block with no attribute. The corresponding source code is located in libvo/gl_common.c:2078:
for (i = 0; i < 4; i++) {
int px = 2*i;
int py = 2*i + 1;
mpglTexCoord2f(texcoords[px], texcoords[py]);
if (is_yv12) {
mpglMultiTexCoord2f(GL_TEXTURE1, texcoords2[px], texcoords2[py]);
mpglMultiTexCoord2f(GL_TEXTURE2, texcoords2[px], texcoords2[py]);
}
if (use_stipple)
mpglMultiTexCoord2f(GL_TEXTURE3, texcoords3[px], texcoords3[py]);
mpglVertex2f(vertices[px], vertices[py]);
}
The block is a for block. There are many more similar lexical_block instances.
My solution consists of two parts:
1) Source code analysis:
Find the scope (surrounding left and right braces) where the target variable is accessed. In fact we only need to store the line number of the left brace.
Find the level of the scope in the tree of scopes (a tree that shows parent/child relationships similar to what can be found in .info.
At this point we have the start line of the scope corresponding to a variable access and the level of the scope in the tree of scopes (e.g., line 12 and level 2 in the code depicted in the original question).
2) DebugInfo analysis:
Now, we can analyze the appropriate CU and look for the declarations of that target variable. The important point is that only the declarations with a line number smaller than the line number of the access point are valid. Considering this, we can search the global scope, and continue with deeper levels, in order.
Declarations with scopes deeper than the scope of the access are invalid. Declarations with the same scope as the target variable are only valid if their line number is between the start line of the target scope and the line number of the variable access.

Stack Smashing Detected in GCC

I'm new to C and I've found a peculiar output from gcc that I'm having a hard time getting to the bottom of. The error upon running the application is:
*** stack smashing detected ***: /home/joshua/Research/cml/test terminated
Program received signal SIGABRT, Aborted.
0x00007ffff7a43428 in __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
I've done some research on this, and it appears that this is many times caused by tying to put too large a value into an array, for example; I'm not doing anything like that.
Here is my sample code for reference:
1 #include <stdio.h>
2 #include <string.h>
3
4 struct student
5 {
6 int id;
7 char name[10];
8 float percentage;
9 };
10
11 int main()
12 {
13 int i;
14 struct student record[2];
15
16 // 1st student's record
17 record[0].id=1;
18 strcpy(record[0].name, "Raju");
19 record[0].percentage = 86.5;
20
21 // 2nd student's record
22 record[1].id=2;
23 strcpy(record[1].name, "Surendren");
24 record[1].percentage = 90.5;
25
26 // 3rd student's record
27 record[2].id=3;
28 strcpy(record[2].name, "Thiyagu");
29 record[2].percentage = 81.5;
30
31 for(i=0; i<3; i++)
32 {
33 printf(" Records of STUDENT : %d \n", i+1);
34 printf(" Id is: %d \n", record[i].id);
35 printf(" Name is: %s \n", record[i].name);
36 printf(" Percentage is: %f\n\n",record[i].percentage);
37 }
38 return 0;
39 }
The 2 in
struct student record[2];
is not the top index, it is the number of elements. And as you seem to know indexes start at zero which means the valid indexes are 0 and 1 for the above array. Going out of bounds leads to undefined behavior.
struct student record[2];
You've got an array of size 2 and you're trying to store 3 elements in it. Array indices go from 0 to n-1. record[2] is an invalid index.
To keep a check on the integrity of the functions, next to the return statement Gcc adds protection variables (called canaries) which have known values.In your case when the uninitialized access is done on record[2] you have violated the stacks integrity and the canary values are overwritten which trigger the crash.

C program to check lottery numbers: why some tests fail?

This program takes as an input the following lines:
23 12 33 19 10 8
5
23 19 8 12 60 18
14 60 12 44 54 10
8 3 12 19 33 10
33 15 7 60 12 10
22 12 19 23 33 11
23 12 33 19 10 8 ( The first line ) are the lottery results.
n ( in this specific case, 5 ) informs how many lines will follow below.
Each line has 6 numbers. The number order doesn't matter.
The rules are: numbers range from 1 to 60 ( including 1 and 60 ) and they never repeat themselves in the same line.
The variable "quadra" stores how many lines have got 4 numbers right.
The variable "quina" stores how many lines have got 5 numbers right.
The variable "sena" stores how many lines have got 6 numbers right.
So, a computer program is running some tests over my code below and it's claiming that it goes wrong for most of them, but I can't see what's the problem here. Does anybody have a clue? Is this code wrong, or is there something wrong with the software that's testing this code?
#include <stdio.h>
int main(){
int mega[6];
int v[50500][6];
int n,swap;
int i,j,k; //counters
int quadra,quina,sena;
quadra = 0;
quina = 0;
sena = 0;
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
scanf("%i",&n);
for(i=0;i<n;++i){
for(j=0;j<6;++j){
scanf("%i",&v[i][j]);
}
}
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=0;k<6;++k){
if(v[i][j] == mega[k]){
v[i][j] = 61;
}
}
}
}
//reverse bubble sort
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=j+1;k<6;++k){
if(v[i][j] < v[i][k]){
swap = v[i][k];
v[i][k] = v[i][j];
v[i][j] = swap;
}
}
}
}
for(i=0;i<n;++i){
for(j=0;v[i][j] == 61 && j<6;++j);
if(j == 4) ++quadra;
else if(j == 5) ++quina;
else if(j == 6) ++sena;
}
return 0;
}
Your code is true, I understood and tried the flow of it. Looks fine but if you dont need to sort everyline (and use j as a counter in this loop for(j=0;v[i][j] == 61 && j<6;++j); ), you can use simpler ifstatements to compare real lottery results with the ones that entered. What I mean is that your algorithm is a little complex. Try a simple one and see how it works.
Yes, there are a couple of noteworthy issues with your code:
Compile time indicates possibility of uninitialized variable:
But, run-time results in fatal run-time at unknown source location. Stack overflow. It is likely due to this line:
int v[50500][6];
Increase your stack size. It needs to be about 2.5Mbytes for v alone.
Also, this line may not be what you intended:
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
^
If you meant to loop around the remainder of the code, remove the ; after the for() statement, and use curly braces:
for(i=0;i<6;++i) scanf("%i",&mega[i]) //first line, lottery results
{
scanf("%i",&n);
....

How SubString,Limit Using C? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Section#1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
int main(int argc, char **argv)
{
static const unsigned char text[] = "000ßh123456789";
int32_t current=1;
int32_t text_len = strlen(text)-1;
/////////////////////////////////
printf("Result : %s\n",text);
/////////////////////////////////
printf("Lenght : %d\n",text_len);
/////////////////////////////////
printf("Index0 : %c\n",text[0]);
printf("Index1 : %c\n",text[1]);
printf("Index2 : %c\n",text[2]);
printf("Index3 : %c\n",text[3]);//==> why show this `�`?
printf("Index4 : %c\n",text[4]);//==> why show this `�`?
printf("Index0 : %c\n",text[5]);
/////////////////////////////////
return 0;
}
why text[3] and text[4] show �?
how can also support utf-8 character in Index?
Section#2
I want write a function like mb_substr in php.
(verybigstring or string) mb_substr ( (verybigstring or string) input , (verybigint or int) start [, (verybigint or int) $length = NULL ] )
Some Example:
mb_substr("hello world",0);
==>hello world
mb_substr("hello world",1);
==>ello world
mb_substr_two("hello world",1,3);
==>el
mb_substr("hello world",-3);
==>rld
mb_substr_two("hello world",-3,2);
==>rldhe
My Question is Section#1
Can anyone help me?(please)
The Unicode character set currently includes more than 128,000 characters (which I shall henceforth call Code Points to avoid confusion) with space reserved for far, far more. As such, a char which is only 8 bits in size on modern general-computing machines can't be used to contain a Code Point.
UTF-8 is a way of encoding these Code Points into bytes. The following are the bytes you placed in text[] (assuming UTF-8 was used to encode the Code Points) and what they represent:
i: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
text[i]: 0x30 30 30 C3 9F 68 31 32 33 34 35 36 37 38 39 00
-- -- -- ----- -- -- -- -- -- -- -- -- -- -- --
Code Point: U+30 30 30 DF 68 31 32 33 34 35 36 37 38 39 0
Graph: 0 0 0 ß h 1 2 3 4 5 6 7 8 9
As you can see, UTF-8 is a variable-width encoding. A single Code Points encodes to a variable number of bytes. This means you can't translate indexes-into-text into indexes-into-array-of-bytes without scanning the array.
A Code Point encoded using UTF-8 starts with
0b0xxxxxxx Represents an entire Code Point
0b110xxxxx The start of a 2-byte sequence
0b1110xxxx The start of a 3-byte sequence
0b11110xxx The start of a 4-byte sequence
The only other form of bytes you will encounter in UTF-8 is
0b10xxxxxx A continuation byte (the 2nd, 3rd or 4th byte of sequence)
A simple way to find the nth Code Point in a string (if you assume the input is valid UTF-8) is to search for the nth char for which (ch & 0xC0) != 0xC0 is true. You can use the same approach to count the number of Code Points in a string.

A second getpwuid call appears to overwrite old value

Here's a small C program that prints (well, supposed to print) the real and effective IDs of a process when the file has the setuid flag set. In this program, when I call getpwuid a second time (L.No 38), it tends to overwrite the value of the variable realUserName that was obtained in L.No 24. I'm unable to explain this behavior. Is this the expected behavior and why? I'm trying this in a Linux box (RHEL 2.6.18-371.1.2.el5).
1 /* Filename: test.c
2 * Notes:
3 * 1] ./test owned by user cadmn (userID: 3585)
4 * 2] ./test run by user pmn (4471)
5 * 3] ./test has the setuid bit switched-on.
6 */
7 #include <stdio.h>
8 #include <pwd.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11 int main()
12 {
13
14 uid_t realId, effectiveId;
15 struct passwd *realUser, *effUser;
16
17 realId = getuid(); // realId = 4471
18 effectiveId = geteuid(); //effectiveId = 3585
19
20 printf("Real ID is %i and Effective ID is %i\n", (int)realId, (int)effectiveId);
21 //prints 4472 and 3585, respectively
22
23 realUser = getpwuid(realId);
24 char *realUserName = realUser->pw_name; //realUserName = pmn
25
26 printf("Real ID (name) at this point is %s\n", realUserName);
27 // prints pmn.
28
29 /*
30 *********************************************************
31 * *
32 * everything works as expected up to this point *
33 * *
34 *********************************************************
35 */
36
37 // The value obtained from this call is not used anywhere in this program
38 effUser = getpwuid(effectiveId);
39 printf("\nCalled getpwuid with the effectiveId\n\n");
40
41 printf("Real ID is %i and Effective ID is %i\n", (int)realId, (int)effectiveId);
42 //prints 4472 and 3585, respectively
43
44 printf("Real ID (name) at this point is %s.\n", realUserName);
45 // Expect to still see 'pmn' printed; though see 'cadmn' as the output!
46 // Why does this happen?
47
48 return 0;
49 }
50
Output:
pmn#rhel /tmp/temp > id pmn
uid=4471(pmn) gid=1000(nusers) groups=1000(nusers)
pmn#rhel /tmp/temp >
pmn#rhel /tmp/temp > id cadmn
uid=3585(cadmn) gid=401(cusers) groups=401(cusers)
pmn#rhel /tmp/temp >
pmn#rhel /tmp/temp > ls -l ./test
-r-sr-xr-x 1 cadmn cusers 9377 Dec 24 19:48 ./test
pmn#rhel /tmp/temp >
pmn#rhel /tmp/temp > ./test
Real ID is 4471 and Effective ID is 3585
Real ID (name) at this point is pmn
Called getpwuid with the effectiveId
Real ID is 4471 and Effective ID is 3585
Real ID (name) at this point is cadmn.
pmn#rhel /tmp/temp >
The behaviour you observe is the expected one.
The structure referenced by the return value of getpwuid() is defined statically internal to the latter, so it is expected to be filled (and with this overwritten) for each call to getpwuid().
This line
char * realUserName = realUser->pw_name;
just stores a reference to a value held by this statically internal structure. This value is also overwritten if the statically internal structure is overwritten by the next call to getpwuid().
To get around this there are two possibilities:
Use te reentrant version of getpwuid() which is getpwuid_r(). To be able to use it, add
#define _POSIX_SOURCE
before the very 1st #include statement in your program's sources.
Create copy of the members you need, pw_namein this case. The can be achieved by for example doing:
char * realUserName = strdup(realUser->pw_name);
Be awre that realUserName is now pointing to dynamically allocated memory, which needs to be free()ed by the program itself if not need anymore. To do so call
free(realUserName);

Resources