I have a problem with my code. When I run the code the short "opcode" has the wrong value 52496. So I debug the code step by step... and when I am doing this "opcode" has the correct value 4624! Can someone give me a hint?
void packet_get()
{
boost::shared_ptr<boost::array<unsigned char, 2>> opc(new boost::array<unsigned char, 2>);
recv_two_bytes(opc);
unsigned short opcode;
unsigned char * test[2];
test[0] = &opc->at(0); // *test[0] == 0x12
test[1] = &opc->at(1); // *test[1] == 0x10
opcode = 0;
int i = 0;
for(i = 0; i <= 1; i++)
{
opcode = (opcode<<8) | *(test[i]);
}
// opcode should now be short 4624
}
Usually, when the behavior of the program is different between normal and debug runs, it is due to an undefined behavior. One such common mistake is uninitialized variables.
When you execute a program, it is given a stack that is most likely uninitialized. In debug mode, it is possible for the debugger to initialize this stack. Therefore, an uninitialized variable can easily have different values in debug and normal execution (even 0 in debug mode, which most of the times is what you actually wanted to give the variable but forgot).
It seems like you have some error like that in your recv_two_bytes function. Enabling all warnings on your compiler will help pin down the problem if it is more trivial.
Be on the look out for other errors such as indexing out of array also.
Related
I am attempting to write a program which loops through all ASCII characters, selects those which are letters, appends them to a string and then outputs this string. I have written the following code:
#include <iostream>
#include <string>
#include "ctype.h"
using namespace std;
int main()
{
string str;
for (char k = 0; k <= 255; k++)
if (isalpha(k) != 0) {
str += k;
}
cout << str << '\n';
}
However, when I run this code I get a 'bad_alloc' error, which to my understanding means I ran out of memory. Thus, I must have done something terribly wrong in my code. I am very new to C++ in general, could someone point out my (possibly many) mistakes?
You should enable all warnings when you compile your code (-Wall -Wextra). Doing so would result in the following message by the compiler:
clang:
result of comparison of constant 255 with expression of type 'char' is always true [-Wtautological-constant-out-of-range-compare]
gcc:
warning: comparison is always true due to limited range of data type [-Wtype-limits]
Depending on the compiler and the target platform the signedness of char depends can vary. The defaults for ARM and PowerPC are typically unsigned, the defaults for x86 and x64 are typically signed.
The range of char, if signed, is -128 to 127, to be platform-independent, you need to ensure that you use unsinged char, but even then you would have the problem that <=255 would produce the same bad_alloc error, as the maximum value of a unsigned char is 255, so you have to use `k < 255;':
for (unsigned char k = 0; k < 255; k++)
On many platforms, char is signed. That means it goes to 127 then "overflows".
Overflowing has undefined behaviour, but sometimes that looks like a "wrap-around" to a negative value. The result is that k will always be less than 255, so your loop will never end, and you'll keep trying to add characters to the string forever, or until you run out of memory (boom).
Indeed even if you use an unsigned char, you're still never going to get above 255.
Use an int instead.
Your call to isalpha also has undefined behaviour, for similar reasons (refer to the documentation for functions that you use).
Change for (char k = 0; k <= 255; k++) to for (int k = 0; k <= 255; k++) then it will be fine.
Reason:
Char on the system is signed character, hence it's range is 2^n - 1 to -(2^n) - 1 where n is 8 (you can check it by printing macro CHAR_BIT).
So when the loop for k reaches 127 and goes for the next value, it becomes -128 as the value wraps around & then it becomes the infinite loop.
You can verify this by:
char c=127;
char d=c+1;
printf("%d\n",d);
OUTPUT: -128
I've been trying all day how to read properly the memory of a game with my injected DLL, it works correctly but if the DLL reach other type of variable which is not "float" then it crashes. My question is, how can I detect if is float and avoid crashes. Here is my code:
for (DWORD i = 0x1000000; i < 0x2FFFFFF; i += 0x4)
{
DWORD Base = *(DWORD*)(base + i);
DWORD lvl_2 = *(DWORD*)(Base + 0x8);
float* posx = static_cast<float*>((float*)(lvl_2 + 0x90));
Position_x = static_cast<float>(*posx);
if (Position_x > 7.05f && Position_x < 7.20f) //test > 7.05f && test < 7.20f || i == 0x2217710
{
fprintf(file, "Pointer: 0x%x Position x: %.2f \n", i, Position_x);
}
}
This is a scanner I made to update pointer of a game knowing the structs offsets. This code works correctly if I use as condition i == 0x2217710, it returns the correct position x of the player. If I remove the condition it crashes due to the line Position_x = static_cast... is converting other type of variable in float which is illegal for some variables. How could I do this? Thanks in advance.
First, I'm pretty sure the problem isn't that it crashes when you have a pointer that isn't to a float. All binary values 0 - 0xFFFFFFFF are generally valid as float values, but some are "special", such as "not a number" - but as long as you only compare the value, etc, it will work just fine to use such values too - will just come out as false in the comparison.
Your actual problem is that you are making a pointer from base+i, and then using the content at that location as another pointer - but if base+i does not hold a valid pointer {which is pretty much most 32- or 64-bit values in most systems}, then your next fetch will go wrong. Unfortunately, there is no trivial way to check if a memory address is valid or not. In Windows, you could possibly use __try, __except to catch when you are trying to read an invalid memory address and "do something else".
I have try the following code to judge prime:
const int N = 200000;
long prime[N] = {0};
long num_prime = 0;
int is_not_prime[N]={1,1};
void Prime_sort(void)
{
for( long i = 2 ; i<N ; i++ )
{
if( !is_not_prime[i] )
{
prime[num_prime++] = i;
}
for( long j = 0; j<num_prime && i*prime[i]<N ; j++ )
{
is_not_prime[i*prime[j]] = 1;
}
}
}
But when I run it, it cause a segmentation fault! That fault I have never meet.And I searched Google,and it explain segmentation fault as follow:
A segmentation fault (often shortened to segfault) is a particular
error condition that can occur during the operation of computer
software. In short, a segmentation fault occurs when a program
attempts to access a memory location that it is not allowed to access,
or attempts to access a memory location in a way that is not allowed
But I don't know where cause this fault in my code.Please help me.
Your array is_not_prime has length N. For example, at the final lap of the outer for loop, i will have the value N-1. When i is that big, is_not_prime[i*prime[j]] will cause you to write far out of bounds of the array.
I'm not quite sure what j<num_prime && i*prime[i]<N is supposed to do, but it is likely part of the bug. Single step through the program with your debugger and see at what values the variables have when the program crashes.
Just re-write your program in a less complex manner and all bugs will go away.
Compare your loop bound checking to your indexing - they aren't the same. (I believe you meant to write i*prime[j]<N in your for loop.)
Your program crashes because an index goes out of bounds. And the index goes out of bounds because your algorithm is not valid.
As it still crashes if you set N at a much smaller value
const int N = 3;
it shouln't be too difficult to see what goes wrong by running your program with pencil and paper...
I just ran into a free(): invalid next size (fast) problem while writing a C++ program. And I failed to figure out why this could happen unfortunately. The code is given below.
bool not_corrupt(struct packet *pkt, int size)
{
if (!size) return false;
bool result = true;
char *exp_checksum = (char*)malloc(size * sizeof(char));
char *rec_checksum = (char*)malloc(size * sizeof(char));
char *rec_data = (char*)malloc(size * sizeof(char));
//memcpy(rec_checksum, pkt->data+HEADER_SIZE+SEQ_SIZE+DATA_SIZE, size);
//memcpy(rec_data, pkt->data+HEADER_SIZE+SEQ_SIZE, size);
for (int i = 0; i < size; i++) {
rec_checksum[i] = pkt->data[HEADER_SIZE+SEQ_SIZE+DATA_SIZE+i];
rec_data[i] = pkt->data[HEADER_SIZE+SEQ_SIZE+i];
}
do_checksum(exp_checksum, rec_data, DATA_SIZE);
for (int i = 0; i < size; i++) {
if (exp_checksum[i] != rec_checksum[i]) {
result = false;
break;
}
}
free(exp_checksum);
free(rec_checksum);
free(rec_data);
return result;
}
The macros used are:
#define RDT_PKTSIZE 128
#define SEQ_SIZE 4
#define HEADER_SIZE 1
#define DATA_SIZE ((RDT_PKTSIZE - HEADER_SIZE - SEQ_SIZE) / 2)
The struct used is:
struct packet {
char data[RDT_PKTSIZE];
};
This piece of code doesn't go wrong every time. It would crash with the free(): invalid next size (fast) sometimes in the free(exp_checksum); part.
What's even worse is that sometimes what's in rec_checksum stuff is just not equal to what's in pkt->data[HEADER_SIZE+SEQ_SIZE+DATA_SIZE] stuff, which should be the same according to the watch expressions from my debugging tools. Both memcpy and for methods are used but this problem remains.
I don't quite understand why this would happen. I would be very thankful if anyone could explain this to me.
Edit:
Here's the do_checksum() method, which is very simple:
void do_checksum(char* checksum, char* data, int size)
{
for (int i = 0; i < size; i++)
{
checksum[i] = ~data[i];
}
}
Edit 2:
Thanks for all.
I switched other part of my code from the usage of STL queue to STL vector, the results turn to be cool then.
But still I didn't figure out why. I am sure that I would never pop an empty queue.
The error you report is indicative of heap corruption. These can be hard to track down and tools like valgrind can be extremely helpful. Heap corruptions are often hard to debug with a simple debugger because the runtime error often occurs long after the actual corruption.
That said, the most obvious potential cause of your heap corruption, given the code posted so far, is if DATA_SIZE is greater than size. If that occurs then do_checksum will write beyond the end of exp_checksum.
Three immediate suggestions:
Check for size <= 0 (instead of "!size")
Check for size >= DATA_SIZE
Check for malloc returning NULL
Have you tried Valgrind?
Also, make sure to never send more than RDT_PKTSIZE as size to not_corrupt()
bool not_corrupt(struct packet *pkt, int size)
{
if (!size) return false;
if (size > RDT_PKTSIZE) return false;
/* ... */
Valgrind is good ... but validating all your inputs and checking all error conditions is even better.
Stepping through the code in the debugger isn't a bad idea, either.
I would also call "do_checksum (size)" (your actual size), instead of DATA_SIZE (presumably "maximum size").
DATA_SIZE is a macro defined the max length in my program so the size
should be less than DATA_SIZE
even if that is true, your logic only creates enough memory to hold size characters.
so you should call
do_checksum(exp_checksum, rec_data, size);
and, if you do not want to use std::string (which is fine), you should switch from malloc/free to new/delete when talking C++
I have a class in system-C with some data members as such:
long double x[8];
I'm initializing it in the construction like this:
for (i = 0; i < 8; ++i) {
x[i] = 0;
}
But the first time I use it in my code I have garbage there.
Because of the way the system is built I can't connect a debugger easily. Are there any methods to set a data breakpoint in the code so that it tells me where in the code the variables were actually changed, but without hooking up a debugger?
Edit:
#Prakash:
Actually, this is a typo in the question, but not in my code... Thanks!
You could try starting a second thread which spins, looking for changes in the variable:
#include <pthread.h>
void *ThreadProc(void *arg)
{
volatile long double *x = (volatile long double *)arg;
while(1)
{
for(int i = 0; i < 8; i++)
{
if(x[i] != 0)
{
__asm__ __volatile__ ("int 3"); // breakpoint (x86)
}
}
return 0; // Never reached, but placate the compiler
}
...
pthread_t threadID;
pthread_create(&threadID, NULL, ThreadProc, &x[0]);
This will raise a SIGTRAP signal to your application whenever any of the x values is not zero.
Just use printk/syslog.
It's old-fashioned, but super duper easy.
Sure, it will be garbage!
The code should have been as
for (i = 0; i < 8; ++i) {
x[i] = 0;
}
EDIT: Oops, Sorry for underestimating ;)
#Frank
Actually, that lets me log debug prints to a file. What I'm looking for is something that will let me print something whenever a variable changes, without me explicitly looking for the variable.
How about Conditional breakpoints? You could try for various conditions like first element value is zero or non zero, etc??
That's assuming I can easily connect a debugger. The whole point is that I only have a library, but the executable that linked it in isn't readily available.