Can't Recurse Directories Properly - c++

I am trying to recurse directories in a c++ program I am creating using the QT creator application. For some reason, neither QDir::entryList nor QDirIterator seem to work. Using QDirIterator I can get the second directory down but it goes no further. A similar thing happens when I use QDir::entryList with nested foreach loops. Ultimately, I'd like to get the last directory, which contains no other directories, in a chain of directories.
This is intended to be cross-platform so it cannot be OS specific. I'd also like to avoid lots of switches for different OS' as I'd like to not have to work on it later and simply use it (potentially forever). I have tried foreach loops, while loops, anything I could think of.
QDir Code:
QStringList GetLastSubDirs(QDir baseDirectory) {
QStringList result;
baseDirectory.setFilter( QDir::Dirs|QDir::NoDotAndDotDot );
QStringList nonEmptyDirs(baseDirectory.path());
while (nonEmptyDirs.size() > 0) {
foreach (QString d, nonEmptyDirs) {
QDir sd(d);
foreach (QDir checkingDir, sd.entryList(QDir::Dirs|QDir::NoDotAndDotDot)) {
if (checkingDir.entryList().size() == 0) {
result.append(checkingDir.path());
} else {
nonEmptyDirs.append(checkingDir.path());
}
}
nonEmptyDirs.removeOne(d);
}
}
if (result.size() == 0) {
result = QStringList(baseDirectory.path());
}
return result;
}
};
Here is the QDirIterator code:
class Directories
{
public:
QStringList GetLastSubDirs(QDir baseDirectory) {
QStringList result;
baseDirectory.setFilter( QDir::Dirs|QDir::NoDotAndDotDot );
QDirIterator it(QDir::currentPath() + "/" + baseDirectory.path(), QDirIterator::Subdirectories);
while(it.hasNext()) {
QDir curWorkDir(it.path());
curWorkDir.setFilter( QDir::Dirs|QDir::NoDot|QDir::NoDotDot );
if(curWorkDir.entryList().size() >= 1) {
foreach (QDir d, curWorkDir.entryList()) {
d.setFilter( QDir::Dirs|QDir::NoDot|QDir::NoDotDot );
if (d.entryList().size() <= 0) {
result.append(d.path());
}
}
} else {
result.append(curWorkDir.path());
}
it.next();
}
if (result.size() == 0) {
result = QStringList(baseDirectory.path());
}
return result;
}
};
Debugger Output
1 Directories::GetLastSubDirs main.cpp 56 0x555555559ba9
2 Games::Games main.cpp 80 0x555555559f98
3 __static_initialization_and_destruction_0 main.cpp 104 0x55555555931b
4 _GLOBAL__sub_I_main.cpp(void) main.cpp 120 0x55555555934e
5 __libc_csu_init 0x55555555cd9d
6 __libc_start_main libc-start.c 247 0x7ffff54ed270
7 _start 0x555555558f2a
Disassembler output:
0x555555558f00 31 ed xor %ebp,%ebp
0x555555558f02 <+ 2> 49 89 d1 mov %rdx,%r9
0x555555558f05 <+ 5> 5e pop %rsi
0x555555558f06 <+ 6> 48 89 e2 mov %rsp,%rdx
0x555555558f09 <+ 9> 48 83 e4 f0 and $0xfffffffffffffff0,%rsp
0x555555558f0d <+ 13> 50 push %rax
0x555555558f0e <+ 14> 54 push %rsp
0x555555558f0f <+ 15> 4c 8d 05 aa 3e 00 00 lea 0x3eaa(%rip),%r8 # 0x55555555cdc0 <__libc_csu_fini>
0x555555558f16 <+ 22> 48 8d 0d 33 3e 00 00 lea 0x3e33(%rip),%rcx # 0x55555555cd50 <__libc_csu_init>
0x555555558f1d <+ 29> 48 8d 3d 74 01 00 00 lea 0x174(%rip),%rdi # 0x555555559098 <main(int, char**)>
0x555555558f24 <+ 36> ff 15 c6 70 20 00 callq *0x2070c6(%rip) # 0x55555575fff0
0x555555558f2a <+ 42> f4 hlt
I expect this particular snippet of code to recurse directories until it has cleared any directory that contains other directories. Instead it will only go down one level and stop. For some reason when querying the entryList().size() of these directories it always comes back with 0, even if the directory contains other directories, unless I include . and .. and then it just loops forever because it wasn't intended to handle that.

I don't know why you make it so complicated. The documentation says this:
The QDirIterator class provides an iterator for directory entrylists.
You can use QDirIterator to navigate entries of a directory one at a time. It is similar to QDir::entryList() and QDir::entryInfoList(), but because it lists entries one at a time instead of all at once, it scales better and is more suitable for large directories. It also supports listing directory contents recursively, and following symbolic links. Unlike QDir::entryList(), QDirIterator does not support sorting.
The QDirIterator constructor takes a QDir or a directory as argument. After construction, the iterator is located before the first directory entry. Here's how to iterate over all the entries sequentially:
QDirIterator it("/etc", QDirIterator::Subdirectories);
while (it.hasNext()) {
qDebug() << it.next();
// /etc/.
// /etc/..
// /etc/X11
// /etc/X11/fs
// ...
}
QDirIterator is already recursive when supplying QDirIterator::Subdirectories.

QDir::EntryList returns the names of the child entries, not their full paths. You need to append the name to the parent path to get the full path.
Given a hierarchy:
basedir/
child1/
child2/
grandchild1/
grandchild2/
calling entryList on baseDir will return ["child1", "child2"], not ["basedir/child1", "basedir/child2"]
As I said in the comments: I do not expect this code to work even when you fix that problem. You are modifying nonEmptyDirs inside a foreach loop over nonEmptyDirs. That feels dangerous. It certainly wouldn't work inside a C++11 ranged-for loop. I suggest writing the foreach macro out by hand to check that it will work. In particularly, removing the entry in a list which the current iterator points to, is not going to end well.

From the Qt documentation ... last sentence most important
Qt automatically takes a copy of the container when it enters a foreach loop. If you modify the container as you are iterating, that won't affect the loop. (If you do not modify the container, the copy still takes place, but thanks to implicit sharing copying a container is very fast.)
Since foreach creates a copy of the container, using a non-const reference for the variable does not allow you to modify the original container. It only affects the copy, which is probably not what you want.

Related

in c++ is there any way specialise a function template for specific values of arguments

I have a broadly used function foo(int a, int b) and I want to provide a special version of foo that performs differently if a is say 1.
a) I don't want to go through the whole code base and change all occurrences of foo(1, b) to foo1(b) because the rules on arguments may change and I dont want to keep going through the code base whenever the rules on arguments change.
b) I don't want to burden function foo with an "if (a == 1)" test because of performance issues.
It seems to me to be a fundamental skill of the compiler to call the right code based on what it can see in front of it. Or is this a possible missing feature of C++ that requires macros or something to handle currently.
Simply write
inline int foo(int a, int b)
{
if (a==1) {
// skip complex code and call easy code
call_easy(b);
} else {
// complex code here
do_complex(a, b);
}
}
When you call
foo(1, 10);
the optimizer will/should simply insert a call_easy(b).
Any decent optimizer will inline the function and detect if the function has been called with a==1. Also I think that the entire constexpr mentioned in other posts is nice, but not really necessary in your case. constexpr is very useful, if you want to resolve values at compile time. But you simply asked to switch code paths based on a value at runtime. The optimizer should be able to detect that.
In order to detect that, the optimizer needs to see your function definition at all places where your function is called. Hence the inline requirement - although compilers such as Visual Studio have a "generate code at link time" feature, that reduces this requirement somewhat.
Finally you might want to look at C++ attributes [[likely]] (I think). I haven't worked with them yet, but they are supposed to tell the compiler which execution path is likely and give a hint to the optimizer.
And why don't you experiment a little and look at the generated code in the debugger/disassemble. That will give you a feel for the optimizer. Don't forget that the optimizer is likely only active in Release Builds :)
Templates work in compile time and you want to decide in runtime which is never possible. If and only if you really can call your function with constexpr values, than you can change to a template, but the call becomes foo<1,2>() instead of foo(1,2); "performance issues"... that's really funny! If that single compare assembler instruction is the performance problem... yes, than you have done everything super perfect :-)
BTW: If you already call with constexpr values and the function is visible in the compilation unit, you can be sure the compiler already knows to optimize it away...
But there is another way to handle such things if you really have constexpr values sometimes and your algorithm inside the function can be constexpr evaluated. In that case, you can decide inside the function if your function was called in a constexpr context. If that is the case, you can do a full compile time algorithm which also can contain your if ( a== 1) which will be fully evaluated in compile time. If the function is not called in constexpr context, the function is running as before without any additional overhead.
To do such decision in compile time we need the actual C++ standard ( C++20 )!
constexpr int foo( int a, int)
{
if (std::is_constant_evaluated() )
{ // this part is fully evaluated in compile time!
if ( a == 1 )
{
return 1;
}
else
{
return 2;
}
}
else
{ // and the rest runs as before in runtime
if ( a == 0 )
{
return 3;
}
else
{
return 4;
}
}
}
int main()
{
constexpr int res1 = foo( 1,0 ); // fully evaluated during compile time
constexpr int res2 = foo( 2,0 ); // also full compile time
std::cout << res1 << std::endl;
std::cout << res2 << std::endl;
std::cout << foo( 5, 0) << std::endl; // here we go in runtime
std::cout << foo( 0, 0) << std::endl; // here we go in runtime
}
That code will return:
1
2
4
3
So we do not need to go with classic templates, no need to change the rest of the code but have full compile time optimization if possible.
#Sebastian's suggestion works at least in the simple case with all optimisation levels except -O0 in g++ 9.3.0 on Ubuntu 20.04 in c++20 mode. Thanks again.
See below disassembly always calling directly the correct subfunction func1 or func2 instead of the top function func(). A similar disassembly after -O0 shows only the top level func() being called leaving the decision to run-time which is not desired.
I hope this will work in production code and perhaps with multiple hard coded arguments.
Breakpoint 1, main () at p1.cpp:24
24 int main() {
(gdb) disass /m
Dump of assembler code for function main():
6 inline void func(int a, int b) {
7
8 if (a == 1)
9 func1(b);
10 else
11 func2(a,b);
12 }
13
14 void func1(int b) {
15 std::cout << "func1 " << " " << " " << b << std::endl;
16 }
17
18 void func2(int a, int b) {
19 std::cout << "func2 " << a << " " << b << std::endl;
20 }
21
22 };
23
24 int main() {
=> 0x0000555555555286 <+0>: endbr64
0x000055555555528a <+4>: push %rbp
0x000055555555528b <+5>: push %rbx
0x000055555555528c <+6>: sub $0x18,%rsp
0x0000555555555290 <+10>: mov $0x28,%ebp
0x0000555555555295 <+15>: mov %fs:0x0(%rbp),%rax
0x000055555555529a <+20>: mov %rax,0x8(%rsp)
0x000055555555529f <+25>: xor %eax,%eax
25
26 X x1;
27
28 int b=1;
29 x1.func(1,b);
0x00005555555552a1 <+27>: lea 0x7(%rsp),%rbx
0x00005555555552a6 <+32>: mov $0x1,%esi
0x00005555555552ab <+37>: mov %rbx,%rdi
0x00005555555552ae <+40>: callq 0x55555555531e <X::func1(int)>
30
31 b=2;
32 x1.func(2,b);
0x00005555555552b3 <+45>: mov $0x2,%edx
0x00005555555552b8 <+50>: mov $0x2,%esi
0x00005555555552bd <+55>: mov %rbx,%rdi
0x00005555555552c0 <+58>: callq 0x5555555553de <X::func2(int, int)>
33
34 b=3;
35 x1.func(1,b);
0x00005555555552c5 <+63>: mov $0x3,%esi
0x00005555555552ca <+68>: mov %rbx,%rdi
0x00005555555552cd <+71>: callq 0x55555555531e <X::func1(int)>
36
37 b=4;
38 x1.func(2,b);
0x00005555555552d2 <+76>: mov $0x4,%edx
0x00005555555552d7 <+81>: mov $0x2,%esi
0x00005555555552dc <+86>: mov %rbx,%rdi
0x00005555555552df <+89>: callq 0x5555555553de <X::func2(int, int)>
39
40 return 0;
0x00005555555552e4 <+94>: mov 0x8(%rsp),%rax
0x00005555555552e9 <+99>: xor %fs:0x0(%rbp),%rax
0x00005555555552ee <+104>: jne 0x5555555552fc <main()+118>
0x00005555555552f0 <+106>: mov $0x0,%eax
0x00005555555552f5 <+111>: add $0x18,%rsp
0x00005555555552f9 <+115>: pop %rbx
0x00005555555552fa <+116>: pop %rbp
0x00005555555552fb <+117>: retq
0x00005555555552fc <+118>: callq 0x555555555100 <__stack_chk_fail#plt>
End of assembler dump.

How to Fix the Instruction in Code which cause application crash

The main application file is crashing becausing The server is affected by a format string bug when handles the players nicknames due the access to
an invalid memory zone.
The instruction executed is "cmp [EAX], 00000000" where EAX contains 4
of the bytes in the nickname and Crashes the Server.
I debugged and found that "%s" is missing before the logging string passed to the File_printf function. So i have tried to add this string via IDA Debugger and Successed. After entering these bytes now the server is crashing with the message "server is not vulnerable" before it was crashing with the message "server is vulnerable"
CODE
Bytes I have entered to patch the application:
RVA
00400000
OFFSET
0041dfad cc 68 ; push 0061d0dc
+ cc |0061d0dc
+ cc e8 ; call 0040d270
+ cc ^0040d270
+ cc 83 ; add esp,04
+ cc c4
+ cc 04
+ cc e9 ; jmp 0041e059
+ cc ^0041e059
0041e054 e8 e9 ; jmp 0041dfad
+ ?? ^0041dfad
0055DD63 cmp dword ptr [eax], 0
/*source*/
if ( *(_DWORD *)a1 )
a1 = sub_445D50();
if ( v2 )
{
--*(_DWORD *)(v2 + 4);
*(_DWORD *)a1 = *(_DWORD *)(v2 + 20);
*(_DWORD *)(v2 + 20) = a1;
}
else
{
v3 = *(_DWORD *)((a1 - 4) & 0xFFFFFFFC);
--dword_798ABD0;
sub_445D50();
memset(*(void **)(v3 + 8), 0xCDu, *(_DWORD *)(v3 + 16));
free((void *)v3);
}
}
/Hex Value/
0055DD63 83 38 00
After Testing the Server to Crash then the server Crashed with the message in the testing tool "Server is not Vulnerable" but Crashed.
And in the Debugger IDA i get this result with the detailed Message:
55dd63: The Instruction at 0x55DD63 referenced memory at 0x61616161, The memory could not be read -> 61616161 (exc.code c0000005, tid 4692)
Image 1
Image 2
Image 3
Image 4
Image 5
I can Share the testing tool also but not here because the testing tool has .simplese trojan and it may harm your pc, but i can share the Source code of the testing tool on Request.
The bug is caused by the logging function NetManager_LogMessage which
takes the text to dump, adds a timestamp (using snprintf) and then
passes the whole string to the function File_printf without the needed
format argument (%s) and you need to using the value 05 instead of 04 to make an ampty space to fool the bug. This trick work on many games and good luck

Evaluating Bridge Hands in C++

I am working on a program that is supposed to read in a file (each line in the file represents a hand of 13 cards) and evaluate each bridge hand.
I will ask my specific questions at the end, but because there is a good bit to this program I am going to include all the instructions so you get an idea of what is required.
Here is the text file that will be read in:
2C QD TC AD 6C 3D TD 3H 5H 7H AS JH KH
3C 4C 2D AC QC 7S 7C TD 9C 4D KS 8D 6C
2C 3C KC JC 4C 8C 7C QC AC 5C 9C 6C TC
5H 3S 4D KC 9S 3D 4S 8H JC TC 8S 2S 4C
2S 5D 6S 8S 9D 3C 2H TH
2H 6D %S 8S 7S 4D 3H 4S KS QH JH 5C 9S
2C QD TC AD 6C 3D TD 3C 5H 7H AS JH KD QS
2C QD TC AD 6C 3D TD 2C 5D 7H AS JH KD
2H 6D TS 8Z 7S 4D 3H 4S KS QD JH 5C 9S
With each pair representing a card (the value and the suit).
Legal values include:
2-9
T(10), A(Ace), K(King), Q(Queen), and J(Jack)
And suits:
C(Clubs), S(Spades), D(Diamonds), and H(Hearts)
Once the file is read in, each hand must be sorted first by suit and then by the rank within the suit (aces are high). When the sorting is complete, each hand must be evaluated using the following rules:
Aces = 4
Kings = 3
Queens = 2
Jacks = 1
voids (no cards in a suit) = 3
singletons (one card in a suit) = 2
doubletons (two cards in a suit) = 1
long suits (more than 5 cards in a suit) = 1 count for each card over 5 in number
After being evaluated, each hand should be displayed in the following format:
Example Input:
2C QD TC AD 6C 3D TD 3H 5H 7H AS JH KH
Example Output:
Clubs 10 6 2
Diamonds A Q 10 3
Hearts K J 7 5 3
Spades A
Points = 16
Here are a few specifics about what the program must include:
1. A data structure to hold cards in an ordered manner.
2. A function to read in the hand.
3. A function to evaluate the hand (with support functions).
4. A function to display the hand.
Here is what little code I've been able to come up with. In case it's not clear, the comments are steps I think will need to be done in order for the program to work properly. Right now all it does is open the file, and yes I will be removing the "File is Open" message, I just wanted to be sure the file was actually being open.
//#include <program3.h>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main() {
//Create Array
//char bridgeHands[];
//Open file, if it doesn't exist, exit the program
ifstream bridgeFile;
bridgeFile.open("prog3.dat");
if(!bridgeFile) {
cerr << "Open Failure" << endl;
exit(1);
}
else {
//Read file into array
//Sort array
//Evaluate hands
//Display hands
cout << "File is open" << endl;
}
return 0;
}
I guess my specific question at the moment is this. How do I need to go about creating and loading the array? I have never worked with loading an array from input that is in pairs. Also, how does this work with the data structure?
I'm sure you can tell by now that I'm extremely new at this and am learning as I go (pretty much everything I know how to do in C++ is written in that code), so any help is greatly appreciated. Thank you for your time.
There are a lot of open questions in my mind. First and
foremost: should each hand be on a separate line, or is it just
the next 13 cards, regardless of line breaks. This changes the
way you read hands. In either case, your input file has errors
which must be detected: in the first case, the fifth and seventh
lines have an incorrect format, and in the second, the number of
cards isn't a multiple of 13, so there must be an error
somewhere.
Anyway, the proper way to approach this is to define types
(classes) for the cards and the hand, and defined a user defined
operator>> for each, with the operator>> for hands using the
one for cards. For example:
std::istream& operator>>( std::istream& source, Card& object)
{
char value;
char suit;
source >> std::ws; // skip leading whitespace.
source.get(value); // these do _not_ skip whitespace
source.get(suit);
if ( source ) { // no errors on input...
// Map the characters to the internal representation and write
// them into `object`. This operator may have to be a friend
// to do this.
//
// If one of the characters isn't legal:
// source.setstate( std::ios_base::failbit );
}
return source;
}
For the hand, if your input is line oriented, the best solution
is probably to use std::getline to read the line, then
std::istringstream to parse it. Make sure you check that
there is nothing but white space left once you've read the 13
cards. (If the input ignores line endings, then just reading 13
cards should be sufficient.) Regardless of the strategy, be
sure the check for errors after each read, before using the
values you've read. So you're loop (either on the
std::istringstream or the original source, depending) might
look something like:
int i = 0;
while ( i != 13 && source >> dest[i] ) {
++ i;
}
if ( i == 13 ) {
// Input of 13 cards succeeded...
}
Finally: You're input contains errors (probably intentionally,
to ensure that you test them correctly). Which means the
simplest form of the outer loop won't work correctly (since it
will stop at the first error). If we suppose line oriented
input globally, but the >> operator for hand ignores line
endings and just looks for the next 13 Card:
std::string line;
int lineNumber = 0;
while ( std::getline( source, line ) ) {
++ lineNumber;
std::istringstream parser( line );
if ( parser >> hand >> std::ws && parser.get() == EOF) {
// Line is good, hand contains the instance to be evaluated
} else {
std::cerr << "Input format error in line " << lineNumber << std::endl;
}
}
Concering the condition in the if: we read a hand, then skip
white space; if that succeeds, we verify that we have reached
end of file (otherwise, there's extra garbage at the end of the
line). You can give a more detailed error message if you
separate these different operations out, although to indicate
which card is in error, you'll have to input the 13 cards
directly at this level, rather than using the >> for Hand.
One other suggestion: I would choose an internal representation
which made processing simple, with mapping functions for input
and output. This is probably two enums: one for values (with
the values in the order of their ranking), one for suits (also
in the order of their ranking). This will make the sorting
and the counting significantly easier, and mapping functions are
very easy: for small sets like these, nothing more than an array
with the legal representations: on input, a linear search, and
on output, just index. (Note that this may result in the value
2 having the numeric value 0 internally, since it will be
the first value of the enum.)
Use the ifstream::getline() function for reading and parsing the file. At this link you also find a nice example how you might read the file directly into a std::array:
#include <iostream>
#include <sstream>
#include <vector>
#include <array>
int main()
{
std::istringstream input("abc|def|gh");
std::vector<std::array<char, 4>> v;
// note: the following loop terminates when std::ios_base::operator bool()
// on the stream returned from getline() returns false
for (std::array<char, 4> a; input.getline(&a[0], 4, '|'); ) {
v.push_back(a);
}
for (auto& a : v) {
std::cout << &a[0] << '\n';
}
}
But take a close look whether this is suitable for your case. As an alternative you could omit the last parameter of getline so you really get the lines one by one. Then you'd have to parse these lines using std::string::find() and std::string::substr().

Override function call in VxWorks

My problem is the following. I have a code unit composed of various c files, say for example
file1.c
file2.c
file3.c
that are all compiled with GCC to a unique object "object.o", which in turn is then linked with other objects to give at the end the executable "application.out", running on VxWorks.
Since I'm doing unit testing on "object.o", my need is to stimulate all the possible ways through the code. Specifically, there are situations where I should have mock functions executed instead of original ones in order to simulate error occurrences.
Suppose for example that there is a function "func_caller" that I'm trying to test that, at some point in the execution, makes a call to another function "func_called" (declared as static).
Since I DON'T WANT TO MODIFY THE ORIGINAL CODE, I wonder if there is a way to manipulate the instruction pointers in such a way that when "func_called" is called, it actually executes another mock function "func_called_mock" and the caller "func_caller" does not notice anything.
Thanks in advance.
The most direct method of overriding function calls would be to use VxWorks's load time linking. Consider the following source:
file1.c:
#include <stdio.h>
int function1 (void);
int function1 ()
{
printf ("function1 called\n");
return 1;
}
file2.c:
#include <stdio.h>
int function2 (void);
int function2 ()
{
printf ("function2 called\n");
return 2;
}
file3.c:
int function1 (void);
int function2 (void);
int function3 (void);
int function3 ()
{
function1 ();
function2 ();
return 0;
}
mock.c:
#include <stdio.h>
int function1 (void);
int function2 (void);
int function1 ()
{
printf ("mock function1 called\n");
return 1;
}
int function2 ()
{
printf ("mock function2 called\n");
return 2;
}
When you load an object, its functions are added to the global symbol table.
-> ld < file1.o
value = 273740816 = 0x1050f410
-> lkup "function"
function1 0x108b0000 text (file1.o)
value = 0 = 0x0
->
When you load an object that uses functions already in the symbol table, each call will be immediately resolved to the last address associated with that symbol in the table.
-> ld < file2.o
value = 292535232 = 0x116fbbc0
-> ld < file3.o
value = 292537592 = 0x116fc4f8
-> lkup "function"
function1 0x108b0000 text (file1.o)
function2 0x108d0000 text (file2.o)
function3 0x108f0000 text (file3.o)
value = 0 = 0x0
-> l function3
function3:
0x108f0000 55 PUSH EBP
0x108f0001 89 e5 MOV EBP, ESP
0x108f0003 56 PUSH ESI
0x108f0004 57 PUSH EDI
0x108f0005 e8 f6 ff fb ff CALL function1
0x108f000a e8 f1 ff fd ff CALL function2
0x108f000f 31 c0 XOR EAX, EAX
0x108f0011 5f POP EDI
0x108f0012 5e POP ESI
0x108f0013 89 ec MOV ESP, EBP
value = 0 = 0x0
-> function3
function1 called
function2 called
value = 0 = 0x0
->
Although l() helpfully displays function names, no symbols are actually loaded into memory with the object. Instead, a call to the last address associated with the function is loaded. So, a previously loaded function may be overridden by loading another function of the same name.
-> unld "file3.o"
value = 0 = 0x0
-> ld < mock.o
value = 292537592 = 0x116fc4f8
-> ld < file3.o
value = 292539496 = 0x116fcc68
-> lkup "function"
function1 0x108f0000 text (mock.o)
function1 0x108b0000 text (file1.o)
function2 0x108f0020 text (mock.o)
function2 0x108d0000 text (file2.o)
function3 0x10910000 text (file3.o)
value = 0 = 0x0
-> l function3
function3:
0x10910000 55 PUSH EBP
0x10910001 89 e5 MOV EBP, ESP
0x10910003 56 PUSH ESI
0x10910004 57 PUSH EDI
0x10910005 e8 f6 ff fd ff CALL function1
0x1091000a e8 11 00 fe ff CALL function2
0x1091000f 31 c0 XOR EAX, EAX
0x10910011 5f POP EDI
0x10910012 5e POP ESI
0x10910013 89 ec MOV ESP, EBP
value = 0 = 0x0
-> function3
mock function1 called
mock function2 called
value = 0 = 0x0
->
Note that for this method to work, the called and calling functions cannot be compiled into the same object. You might also note that the addresses to be called don't match those in the symbol table. This is the result of executing the above in VxSim. The VxSim loader actually calls the loader of the underlying operating system. So, these addresses don't match those in the symbol table and the assembly reflects the underlying Pentium architecture on which WorkBench is being run.
A function call may also be overridden by directly manipulating the address to be called in memory. This method is going to be implementation dependent. Below, this is demonstrated for source compiled for PPC using the gcc -mlongcall option. This has been run on an actual target, not VxSim.
-> ld < file1.o
value = 33538216 = 0x1ffc0a8 = function1 + 0x498
-> ld < file2.o
value = 33548336 = 0x1ffe830 = function2 + 0x80
-> ld < mock.o
value = 33549600 = 0x1ffed20 = function2 + 0x570
-> ld < file3.o
value = 33550744 = 0x1fff198 = function2 + 0x9e8
->
-> lkup "function"
function1 0x01ffbef8 text (mock.o)
function1 0x01ffbc10 text (file1.o)
function2 0x01ffbf58 text (mock.o)
function2 0x01ffe7b0 text (file2.o)
function3 0x01ffe558 text (file3.o)
value = 0 = 0x0
->
-> function3
mock function1 called
mock function2 called
value = 0 = 0x0
->
-> l function3
function3:
0x1ffe558 9421ffe8 stwu r1,-24(r1)
0x1ffe55c 7c0802a6 mfspr r0,LR
0x1ffe560 93a1000c stw r29,12(r1)
0x1ffe564 93c10010 stw r30,16(r1)
0x1ffe568 93e10014 stw r31,20(r1)
0x1ffe56c 9001001c stw r0,28(r1)
0x1ffe570 7c3f0b78 or r31,r1,r1
0x1ffe574 3d200200 lis r9,512
0x1ffe578 3ba9bef8 addi r29,r9,-16648
0x1ffe57c 7fa803a6 mtspr LR,r29
value = 33547648 = 0x1ffe580 = function3 + 0x28
->
-> *0x1ffe578
function3 + 0x20 = 0x1ffe578: value = 1000980216 = 0x3ba9bef8
-> *0x1ffe578 = 0x3ba9bc10
function3 + 0x20 = 0x1ffe578: value = 1000979472 = 0x3ba9bc10
-> *0x1ffe578
function3 + 0x20 = 0x1ffe578: value = 1000979472 = 0x3ba9bc10
->
-> function3
function1 called
mock function2 called
value = 0 = 0x0
->
Obviously, directly manipulating pointers in memory is going to quickly become tedious. Additionally, memory protection will prevent you from changing RTPs or objects loaded in VxSim. (Hence, why I ran this on actual hardware.) I mention the possibility, primarily because it seems to best match your question's statement.
Finally, for non-trivial unit testing, you may want to consider a tool designed specifically for the task. Try a search on "vxworks unit test framework". I don't have deep experience with any particular tool (and don't want to come across spammy). Perhaps, someone else here can provide a good suggestion.

C++ IO binary file streams: default value when output isn't specified

My question is about binary file I/O. Suppose the following code is run:
#include <iostream>
#inclide <fstream>
int main(){
fstream out;
out.open("binfile.bin",ios::binary|ios::out);
if(!out.good()){
cout<<"ain't good"<<endl;
return EXIT_FAILURE;
}
out.seekp(3);
out<<char(74);
out.seekp(7);
out<<char(73);
out.close();
}
binfile.bin contains 00 00 00 4A 00 00 00 49, as expected. Can I somehow change that default value that is placed into the file if I don't specify what to output? I would like to replace 00 with something like 30, so that binfile.bin would contain 30 30 30 4A 30 30 30 49, is that doable? Of course I can loop through the file at the end and replace all 00s with 30s, but I'd like to avoid that.
You could write a wrapper for seekp and use that. Pseudocode:
my_seekp(fstream& f, int pos)
{
seek to end
endpos = position at end
if (pos > endpos)
{
int n = endpos - pos;
for (int i = 0; i < n; ++i)
f.put(char(30));
}
else
seek to pos
}
Instead of seeking and writing value as char using <<, what if you allocate a char buf[4] array, set your desired 'fill' value for all the elements, then just update the first/last element with the value you want and call out.write(buf, 4)?