Change variable value of the already running program - c++

I think it is impossible, but I should try.
I have a program, that is doing a physical simulation and recording frames to files. It is recording until the breakup value is not achieved, like:
int counter=0; //global variable
void SomeFunction()
{
...
if(counter == 400) //written exactly by this way, i.e. 400 is not a variable, just a number
PostQuitMessage(0);
else
MakeScreenshot();
counter++;
...
}
The problem is that I forgot to change if(counter == 400) to if(counter == 1000) and now program will be finished with 400 frames, although I need exactly 1000.
I can’t just recompile the program because calculations are very heavy and the program is already running for 2 days, I can’t wait.
It is very important for me, is there any way to change the if statement, or exactly the variable value during the program running?
The only hope I have, is, as far as I remember there was programs that could like change money/health/another stuff in games, and there user exactly could search a variable by value, and change it
Currently it is on about 200-300 frame, I have so little time to fix it.

You can use the Windows functions ReadProcessMemory and WriteProcessMemory.
But you need to determine the position of the value 400. Looking for the value in the running program can be done with the above functions. Depending on the size of the constant, it should be either a USHORT or an UINT.
So you can use the following steps:
Look for the value in a second instance
Isolate the surrounding OpCode sequence.
For example, a cmp xxx, 400
Look for this OpCode sequence in the running executable to find the unique location and replace the crucial value by 1000.
This can be called "hot-patch". It's how simple in-memory cheats do work and requires root privileges.

I downloaded Cheat engine and found address of the counter variable by its value. Through all addresses, the address I need was colored in green.
I changed the value stored at that address to 401, and now all is ok.

Related

Parallel Writes to NFS-backed File

UPDATE: I had each node write to a separate file, and when the separate files were concatenated together the result was correct. I also updated the code to attempt a channel flush and file sync after each write of a single record, but there are still issues between nodes 0 and 1, now. If I make Node 0 sleep for a few seconds before it starts its iteration of the coforall loop, the records come out correct. If not, the last few hundred bytes of Node 0's records seem to be reliably overwritten with NULL bytes, up to the start of Node 1's records. The issues between Node 1 and Node 2, and Node 2 and Node 3, seem to not show up anymore.
Additionally, if I suppress either Node 0 or Node 1 from writing, I see the fully-formed records from the un-suppressed node written correctly to the file. In the case that Node 1 is suppressed, I see 9,997 100B records (or 999,700) correct bytes followed by NULL bytes in the file where Node 1's suppressed records would go. In the case that Node 0 is suppressed, I see exactly 999,700 NULL bytes in the file, after which Node 1's records begin.
Original Post:
I'm trying to troubleshoot an issue with parallel writes from different nodes to a shared NFS-backed file on disk. At the moment, I suspect that something is wrong with the way writes to the disk happen on the NFS server.
I'm working on adapting MPI+C code that uses pwrite to write to coordinated chunks of a file. If I try to have the equivalent locales in Chapel write to the file inside of a coforall loop, I end up with the bits of the file around the node boundaries messed up - usually the final few hundred bytes of each node's data are garbled. However, if I have just one locale iterate through the data on all locales and write it, the data comes out correctly. That is, I use the same data structures to calculate the offsets, but only Locale 0 seeks to that offset and performs the writes.
I've verified that the offsets into the file that each locale runs do not overlap, and I'm using a single channel per task, defined from within the on loc do block, so that tasks don't share a single channel.
Are there known issues with writing to a file from different locales? A lot of the documentation makes it seem like this is known to be safe, but an unsubstantiated guess seems to indicate that there are issues with caching of file contents; when examining the incorrect data, the bits that are incorrect seem to be the original data from the file in that location at the beginning of the program.
I've included the relevant routine below, in case you easily spot something I missed. To make this serial, I convert the coforall loc in Locales and on loc do block into a for j in 0..numLocales-1 loop, and replace here.id with j. Please let me know what else would help get to the bottom of this. Thanks!
proc write_share_of_data(data_filename: string, ref record_blocks) throws {
coforall loc in Locales {
on loc do {
var data_file: file = open(data_filename, iomode.cwr);
var data_writer = data_file.writer(kind=ionative, locking=false);
var line: [1..100] uint(8);
const indices = record_blocks[here.id].D;
var local_record_offset = + reduce record_blocks[0..here.id-1].D.size;
writeln("Loc ", here.id, ": record offset is ", local_record_offset);
var local_bytes_offset = terarec.terarec_width_disk * local_record_offset;
data_writer.seek(start=local_bytes_offset);
for i in indices {
var write_rec: terarec_t = record_blocks[here.id].records[i];
line[1..10] = write_rec.key;
line[11..98] = write_rec.value;
line[99] = 13; // \r
line[100] = 10; // \n
data_writer.write(line);
lines_written += 1;
}
data_file.fsync();
data_writer.close();
data_file.close();
}
}
return;
}
Adding an answer here that solved my particular problem, though it doesn't explain the behavior seen. I ended up changing the outer loop from coforall loc in Locales to for loc in Locales. This isn't too big of an issue since it's all writing to one file anyway - I doubt that multiple locales can actually make much headway in all attempting to write concurrently to a single file on an NFS server. As a result, the change still allows nodes to write the data they have locally to NFS, rather than forcing Node 0 to collect and then write the data on behalf of all locales. This amounts to only adding idle time to the write operation commensurate with the time it takes Locale 0 to start the remote task on other nodes when the previous node has finished writing, which for the application at hand is not a concern.
Have you tried specifying start/end in file.writer instead of using seek? Does that change anything? What about specifying the end offset for the channel.seek call? Does it matter if the file is created and has the appropriate size before you start?
Other than that, I wonder if this issue would appear for both NFS and Lustre. If it appears for both it might well be a Chapel bug. It sounds from your description that the C program was using this pattern, which points to it being a bug. But, have you run C code doing this on your setup? If it being a Chapel bug seems most likely after further investigation, we would appreciate a bug report issue with a reproducer.
I know that NFS does not always do what one would like, in terms of data consistency. It's my understanding that it has "close to open" semantics but it's unclear to me what that means in the context of opening a file and writing to a particular region within it, in parallel from different locales.
From Why NFS Sucks by Olaf Kirch:
An NFS client is permitted to cache changes locally and send them to
the server whenever it sees fit. This sort of lazy write-back greatly
helps write performance, but the flip side is that everyone else will
be blissfully unaware of these change before they hit the server. To
make things just a little harder, there is also no requirement for a
client to transmit its cached write in any particular fashion, so
dirty pages can (and often will be) written out in random order.
I read two implications from this paragraph that are relevant to your situation here:
The writes you do on different locales can be observed by the NFS server in an arbitrary order. (However as I understand it, the data should be sent to the server by the time your fsync call returns).
These writes are done at an OS page granularity (usually 4k). (Note that this is more a hypothesis I am making than it is a fact. It should be tested or further investigated).
It would be interesting to check if 2. is a plausible explanation for the behavior you are seeing. For example, you could explore having each locale operate on a multiple of 4096 records (or potentially try writing records of 4096 bytes each) and see if that changes the behavior. If 2 is indeed the explanation, it should be possible to create a C program that demonstrates the behavior as well.

Arduino random() affecting string output

I am currently working on an arduino project using a Teensy 3.2.
The project uses some encryption code that exists in the library folder. When building the encryption code, any padding that was needed was hard-coded until the rest of the encryption worked. With the encryption working, I moved to randomize the padding process.
I am currently using the random() function from Wprogram.h.
When using manual padding, the output seems fine. However as soon as the random number generator is used, the output becomes wild and unintelligible.
When using manual padding:
//st is defined as byte[4][4]
st[0][0]=message; //character from original message, usually 'a' for testing
st[0][1]='1';
st[0][2]='2';
st[0][3]='3';
...
st[3][3]='k';
//Output
//set state: a123CDEF89fghijk //state prior to encryption
//encrypted: ⸮$2⸮⸮k6⸮tʠ&⸮⸮ //this should look funny
//decrypted to: a123CDEF89fghijk //matches plaintext
When using random padding, I've tried a few different ways:
//starting off with one random char for ease of testing
//random value seeded by randomSeed(analogRead(7));
st[0][0]=message;
st[0][1]=byte(random(33,127));//using 33 to 127 to avoid non-print chars
st[0][2]='2';
st[0][3]='3';
...
st[3][3]='k';
//-----Also Trying------
//It almost seemed like the data from the random number generator was flawed
//So I put in a scheme to ensure a hard coded character
if(random(100)%2)
st[0][1]='a';
else
st[0][1]='b';
//--------Also trying----------
//Since it seems like it is simply the existance of the random value that is
// problematic, I tried calling it without using it
int randval=random(100);
st[0][0]=message;
st[0][1]='1';
st[0][2]='2';
st[0][3]='3';
...
st[3][3]='k';
//Typical Output
//set state: a123CDEF89fghijk //state prior to encrypting(random char shows)
//encrypted: *3}3⸮⸮⸮⸮⸮⸮⸮⸮⸮N //this should look funny
//decrypted to: ⸮⸮⸮⸮⸮⸮⸮⸮k⸮-⸮⸮ //this should not look funny
From trying several different ways to create a random character and from also seeing that just the existence of the random value is causing trouble. I am suspecting that there is something buggy about how the random() function works on arduino/teensy.
Something else I noticed after setting up the random number and not using it, is that when I remove this line of code I have to recompile a couple of times before the code works correctly again. This is causing me to suspect the function even more or being buggy.
As I noted in the code samples, I am seeding the random number generator with a unused pin. Even though I would suspect it would be an issue here, I have tried a few different pins just to be safe.
So I guess my questions here might be: does anybody know what might be causing this problem or can possibly suggest and alternate way to get a random value?

Arduino substring doesn't work

I have a static method that searches (and returns) into String msg the value between a TAG
this is the code function:
static String genericCutterMessage(String TAG, String msg){
Serial.print("a-----");
Serial.println(msg);
Serial.print("b-----");
Serial.println(TAG);
if(msg.indexOf(TAG) >= 0){
Serial.print("msg ");
Serial.println(msg);
int startTx = msg.indexOf(TAG)+3;
int endTx = msg.indexOf(TAG,startTx)-2;
Serial.print("startTx ");
Serial.println(startTx);
Serial.print("endTx ");
Serial.println(endTx);
String newMsg = msg.substring(startTx,endTx);
Serial.print("d-----");
Serial.println(newMsg);
Serial.println("END");
Serial.println(newMsg.length());
return newMsg;
} else {
Serial.println("d-----TAG NOT FOUND");
return "";
}
}
and this is output
a-----[HS][TS]5132[/TS][TO]5000[/TO][/HS]
b-----HS
msg [HS][TS]5132[/TS][TO]5000[/TO][/HS]
startTx 4
endTx 30
d-----
END
0
fake -_-'....go on! <-- print out of genericCutterMessage
in that case I want return the string between HS tag, so my expected output is
[TS]5132[/TS][TO]5000[/TO]
but I don't know why I receive a void string.
to understand how substring works I just followed tutorial on official Arduino site
http://www.arduino.cc/en/Tutorial/StringSubstring
I'm not an expert in C++ and Arduino but this looks like a flushing or buffering problem, isn't it?
Any idea?
Your code is correct, this should not happen. Which forces you to consider the unexpected ways that this could possibly fail. There is really only one candidate mishap I can think of, your Arduino is running out of RAM. It has very little, the Uno only has 2 kilobytes for example. It doesn't take a lot of string munching to fill that up.
This is not reported in a smooth way. All I can do is point you to the relevant company page. Quoting:
If you run out of SRAM, your program may fail in unexpected ways; it will appear to upload successfully, but not run, or run strangely. To check if this is happening, you can try commenting out or shortening the strings or other data structures in your sketch (without changing the code). If it then runs successfully, you're probably running out of SRAM. There are a few things you can do to address this problem:
If your sketch talks to a program running on a (desktop/laptop) computer, you can try shifting data or calculations to the computer, reducing the load on the Arduino.
If you have lookup tables or other large arrays, use the smallest data type necessary to store the values you need; for example, an int takes up two bytes, while a byte uses only one (but can store a smaller range of values).
If you don't need to modify the strings or data while your sketch is running, you can store them in flash (program) memory instead of SRAM; to do this, use the PROGMEM keyword.
That's not very helpful in your specific case, you'll have to look at the rest of the program for candidates. Or upgrade your hardware, StackExchange has a dedicated site for Arduino enthusiasts, surely the best place to get advice.

Checking volatile value of address in C++

I'm trying to implement a mailbox write for the Raspberry Pi. According to the info I found, I can write to address 0x2000B8A0 when mailbox is empty, meaning 0x2000B898 has not the last bit set. I wrote it like this:
uint32_t *mailbox = reinterpret_cast<uint32_t*>(0x2000B880);
while((mailbox[6] & 0x80000000) != 0);
mailbox[8] = value + channel;
But the disassembly shows that the value at mailbox[6] is only loaded once, before the loop, then it just repeats the check with that one value.
I could not find a solution because I don't even know the proper words for this problem. I'm sure it's simple but googling brought nothing for this special case.
Answer lies in title of your question.
You should use the following:
volatile uint32_t *mailbox = const_cast<volatile uint32_t *>(reinterpret_cast<uint32_t*>(0x2000B880));
This will make sure the value is loaded each time in your loop. If you see any application not responding, consider adding some sleep or delay or yield in while.

Gdb conditional step based on memory address?

I 'm wondering if it 's possible to create a script that will continue the program 's execution (after a break) step by step based on the memory address value.
So, if I 'm tracing a function and it goes into a high memory value, I 'd call the gdb script until the memory value is below a set value - then it would break again.
I 'm very new to gdb and still reading the manual/tutorials, but I 'd like to know if my goal is possible :) - and if you could bump me to the proper direction, even better ;)
Thanks!
Edit, updated with pseudocode:
while (1) {
cma = getMemoryAddressForCurrentInstruction();
if (cma > 0xdeadbeef) {
stepi;
} else {
break;
}
}
You're talking about the Program Counter (sometimes called the instruction pointer). It's available in gdb as $pc. Your pseudocode can be translated into this actual gdb command:
while $pc <= 0xdeadbeef
stepi
It'll be slow, since it's starting and stopping the program for every instruction, but as far as I know there's no fast way to do it if you don't know exactly what address you're looking for. If you do, then you can just set a breakpoint there:
break *0xf0abcdef
cont
will run until the program counter hits 0xf0abcdef