I asked a question earlier about this program and was able to resolve it--the good news is my program is working now! The bad news is that it only works when I run it through gdb. Whenever I normally compile the program it'll crash, but running it through gdb gives correct output and allows it to exit normally.
I read Dennis Yurichev's post on debugging this sort of problem with the stack or something in gdb, but I'm still pretty new to programming so I have no idea what I am doing.
Here is the output from attaching gdb to the process ID of the program and then dumping the stack:
Breakpoint 1, 0x74337480 in OutputDebugStringA () from C:\WINDOWS\SysWOW64\KernelBase.dll
(gdb) bt
#0 0x74337480 in OutputDebugStringA () from C:\WINDOWS\SysWOW64\KernelBase.dll
#1 0x77478a64 in msvcrt!_invalid_parameter () from C:\WINDOWS\SysWOW64\msvcrt.dll
#2 0x77425a20 in wctype () from C:\WINDOWS\SysWOW64\msvcrt.dll
#3 0x00010001 in ?? ()
#4 0x77493a09 in msvcrt!fscanf_s () from C:\WINDOWS\SysWOW64\msvcrt.dll
#5 0x7749399b in msvcrt!fscanf () from C:\WINDOWS\SysWOW64\msvcrt.dll
#6 0x00401d0d in main () at ZigSort.c:377
I think it's saying it's crashing due to invalid input or something from fscanf, but that doesn't make sense...
The line referenced (main() line 377) is the first fscanf in here:
int main(void)
{
//initializing file pointer
FILE * ifp;
ifp = fopen("zigzag.txt", "r");
int n;
//getting number of values
fscanf(ifp, "%d", &n); //**LINE 377 RIGHT HERE**
//reading values into a queue
queue_t * data = queue_create();
int ipt;
for(int i=0; i<n; i++)
{
fscanf(ifp, "%d", &ipt);
queue_enqueue(data, ipt);
}
//creating a stack of queues
run_stack_t * runstack = run_stack_create();
queue_t * run = queue_create();
//finding runs and pushing them onto the stack
int runs = 0;
int *runpoint = &runs;
while(queue_is_empty(data) != 1)
{
run = extract_next_run(data);
run_stack_push(runstack, run);
*runpoint += 1;
optimizestack(runstack, runpoint);
}
//merging queues together in sorted order
data = run_stack_pop(runstack);
queue_t * merger;
runs -= 1;
for(int i=0; i<runs; i++)
{
merger = run_stack_pop(runstack);
data = merge(merger, data);
}
queue_destroy(merger);
//output
printqueue(data);
//freeing memory
queue_destroy(data);
//run_stack_destroy(runstack, runpoint);
free(runstack);
free(runpoint);
fclose(ifp);
}
and the zigzag.txt file that is read in is here:
10
9 8 7 6 8 4 2 3 2 1
I'm happy to try anything or include any other information that may be necessary, I'm just not sure how to solve this problem.
Thanks in advance!
Related
I got a struct Chat
struct Chat
{
int m_FD;
int m_BindPort;
char m_NameLength;
char* m_Name;
char m_PeerCount;
char** m_PeerList;
} typedef Chat_t;
i'm initializing it with this function:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen+1));
strcpy(this->m_Name, name);
this->m_BindPort = bindPort;
this->m_PeerCount = peerCount;
this->m_PeerList = malloc(sizeof(char*) * peerCount);
for(int i=0; i<peerCount; i++)
{
this->m_PeerList[i] = malloc(sizeof(char) * 16); // enough for xxx.xxx.xxx.xxx\0
strcpy(this->m_PeerList[i], peerList[i]);
}
//Socket initialization for TCP connection...
//Commenting this out doesn't change anything so i'm hiding it for simplification
return 0;
}
After that i'm calling a second function
int chat_communicate(Chat_t* this)
{
printf("2\n");
fflush(stdout);
//Some stuff that doesn't matter because it isn't even called
return retVar;
}
in main like this
void main(void)
{
char* peerList[1];
char username[USERNAME_MAX_LEN];
int initRet;
int loopRet;
Chat_t chat;
peerList[0] = "192.168.2.2";
memset(username, 0, USERNAME_MAX_LEN);
printf("Please enter your user name: ");
scanf("%s", username);
username[USERNAME_MAX_LEN-1] = 0;
initRet = chat_init(&chat, strlen(username), username, 1234, 1, peerList);
printf("File Descriptor: %d\n", chat.m_FD);
printf("Binding Port: %d\n", chat.m_BindPort);
printf("Name Length: %d\n", chat.m_NameLength);
printf("Name: %s\n", chat.m_Name);
printf("Peer Count: %d\n", chat.m_PeerCount);
for(int i=0; i< chat.m_PeerCount; i++)
{
printf("Peer[%d]: %s\n", i, chat.m_PeerList[i]);
}
printf("1");
ret = chat_communicate(&chat);
//Even more Stuff that isn't even called
}
My program outputs the following
File Descriptor: 3
Binding Port: 1234
Name Length: 4
Name: User
Peer Count: 1
Peer[0]: 192.168.2.2
1
Segmentation Fault
It compiles without errors or even warnings.
You can also assume that every string is null-Terminated The stuff i replaced with comments itn't that complicated but just too much to show.
Every value inside the struct is printed with printf right before but when passing this very struct per reference the application crashes.
What i want to know is why i'm getting this Segmentation Fault. Since it appeared while calling a function i thought it is some kind of layout problem but i havn't find anything like that.
Addition:
Because some people weren't able to believe me that the code i hid behind "some stuff" comments doesn't change anything i want to state this here once again. This code just contains a tcp socket communication and only performs read-operations. I also am able to reproduce the error mentioned above without this code so please don't get stuck with it. Parts does not influence the object under observation at all.
Among other potential problems,
this->m_PeerList = malloc(sizeof(char)*peerCount);
is clearly wrong.
m_PeerList is a char **, yet you're only allocating peerCount bytes, which only works if a char * pointer is one byte on your system - not likely.
Replace it with something like
this->m_PeerList = malloc(peerCount * sizeof( *( this->m_peerList ) ) );
Note that sizeof( char ) is always one - by definition.
You're not allocating enough memory for the this->m_Name. It should be on more than this if you want it to store the null-terminated string of the name.
That, or we need more information about the peerList.
Now that you have posted an almost complete code, I was able to spot two problems next to each other:
int chat_init(Chat_t* this, unsigned int nameLen, char* name, unsigned short int bindPort, unsigned int peerCount, char** peerList)
{
this->m_NameLength = nameLen;
this->m_Name = malloc(sizeof(char) * (nameLen + 1)); // correct
//< this->m_Name = malloc(sizeof(char) * nameLen); // wrong
strcpy(this->m_Name, name); // correct
//< memcpy(this->m_Name, name, nameLen); // wrong
...
The lines starting with //< is your original code:
Here you don't allocate enough space, you need to account for the NUL terminator:
this->m_Name = malloc(sizeof(char) * nameLen);
And here you don't copy the NUL terminator:
memcpy(this->m_Name, name, nameLen);
You really need to be aware how strings work in C.
Why don't you debug it yourself. If using GCC, compile your code with options -g -O0. Then run it with gdb:
gdb ./a.out
...
(gdb) r
If it crashes do:
(gdb) bt
This will give exactly where it crashes.
Update: There may be potential problems with your code as found by other users. However, memory allocation related issues will not crash your application just on calling function chat_communicate. There could be different reasons for this behaviour ranging from stack overflow to improper compilation. Without seeing the whole code it is very difficult to tell. Best advice is to consider review comments by other users and debug it yourself.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I've encountered some strange behaviour in my program.
When I run my program 3-4 times and close it immediately, it's starting to give me segmentation faults before it even starts. When I haven't opened it for a while it opens the first 2-3 times without problem and then again seg faults.
I am open to suggestion on what can cause this kind of problem.
The project is quite big so I don't know where exactly to look so if someone wants to see the source code, here you go :
https://github.com/rokn/Helsys3
Let me break down a debugging session for you, but in future you better do that yourself.
If the problem can be easily reproduced, it is quite trivial to fix it:
gdb ./GAME
(gdb) r
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b2d10c in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0
(gdb) bt
#0 0x00007ffff7b2d10c in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0
#1 0x000000000040650c in sprite_free_age ()
#2 0x00000000004065f9 in AGE_SpriteLoad ()
#3 0x0000000000402740 in BattlefieldLoad () at battlefield.c:89
#4 0x0000000000402794 in BattlefieldInit (battlefield=0x1dca440, battlefieldId=1)
at battlefield.c:96
#5 0x0000000000405349 in BattleInitialize (leftTeam=0x60dff0 <leftTeam>,
rightTeam=0x60e010 <rightTeam>, battlefieldId=1) at battle.c:13
#6 0x0000000000401e8f in LoadContent () at main.c:90
#7 0x0000000000401d2b in main (argc=1, argv=0x7fffffffdfc8) at main.c:49
It crashed within SDL, and last thing that called it is sprite_free_age. What's here (AGE/AGE_Sprite.c):
void sprite_free_age(AGE_Sprite *sprite)
{
if( sprite->texture != NULL )
{
SDL_DestroyTexture( sprite->texture );
sprite->texture = NULL;
sprite->Width = 0;
sprite->Height = 0;
}
}
The only SDL call is SDL_DestroyTexture, and NULL check is performed, which means sprite have garbage data (not NULL but still not an SDL texture but rather something else). It was called from AGE_SpriteLoad:
bool AGE_SpriteLoad(AGE_Sprite *sprite, char *path)
{
sprite_free_age(sprite);
SDL_Texture *finalTexture = NULL;
SDL_Surface *loadedSurface = IMG_Load(path);
// ... the rest is omitted
So whenever you call AGE_SpriteLoad, it first tries to drop previous sprite it may've contained. It was called from BattlefieldLoad at battlefield.c:89:
void BattlefieldLoad()
{
assert(AGE_SpriteLoad(&squareWalkable, "Resources/Battlefield/SquareWalkable.png"));
assert(AGE_SpriteLoad(&squareSelected, "Resources/Battlefield/SquareSelected.png"));
assert(AGE_SpriteLoad(&squareEnemy, "Resources/Battlefield/SquareEnemy.png"));
assert(AGE_SpriteCreateBlank(&battlefieldField, LevelWidth, LevelHeight, SDL_TEXTUREACCESS_TARGET));
AGE_ListInit(&objectsList, sizeof(AGE_Sprite));
AGE_Sprite objectSprite;
int i;
char buffer[100];
for (i = 0; i < BATTLEFIELD_OBJECTS_COUNT; ++i)
{
snprintf(buffer, sizeof(buffer), "Resources/Battlefield/Object_%d.png", i+1);
AGE_SpriteLoad(&objectSprite, buffer);
AGE_ListAdd(&objectsList, &objectSprite);
}
}
Here you have uninitialised AGE_Sprite objectSprite, and you're calling AGE_SpriteLoad on it, which tries to drop old data (which is uninitialised => garbage) and (maybe) crashes. First thing coming to mind is that you need to set objectSprite to zero-bytes, either with memset or just by initialising it upon declaration, e.g. AGE_Sprite objectSprite = {};.
I'm getting a segfault when using libCURL in my HTTP flooder that I wrote for load-testing my site.
Here is the relevant code: https://gist.github.com/AppleDash/a26e0ce0b138cd9eacd2 (A bit large to paste here.)
Here's a link to the line it is segfaulting on: https://gist.github.com/AppleDash/a26e0ce0b138cd9eacd2#file-httpflood-improved-c-L57
And here is a backtrace of the segfault:
#0 0x00007ffff760d65b in fwrite () from /usr/lib/libc.so.6
#1 0x00007ffff79656d8 in ?? () from /usr/lib/libcurl.so.4
#2 0x00007ffff797a76b in ?? () from /usr/lib/libcurl.so.4
#3 0x00007ffff7984349 in ?? () from /usr/lib/libcurl.so.4
#4 0x00007ffff7984b11 in curl_multi_perform () from /usr/lib/libcurl.so.4
#5 0x00007ffff797b977 in curl_easy_perform () from /usr/lib/libcurl.so.4
#6 0x0000000000400f42 in flood (structPointer=0x7fffffffe060) at httpflood.c:57
#7 0x00007ffff7bc5124 in start_thread () from /usr/lib/libpthread.so.0
#8 0x00007ffff768b4bd in clone () from /usr/lib/libc.so.6
I don't see why this call would cause a segfault. Any ideas?
I know you're meant to only provide a small sample of relevant code, but here I am providing the whole thing due to the fact that I feel like context is needed here. (The fact it is being run from many threads and such.)
This is your problem:
for (i = 0; i < threadnum; i++) {
struct flood_data ddosData;
memset(&ddosData, 0, sizeof(struct flood_data));
ddosData.url = url;
ddosData.proxy = getProxy();
pthread_create(&threads[i], NULL, flood, (void *)&ddosData);
}
You're allocating a single struct flood_data instance on the stack and passing that to all of the new threads simultaneously. Each time you iterate through the loop, you overwrite the same instance at the same time that threads spawned from earlier iterations might be trying to read from it. Major undefined behavior.
The proper way to do this is to dynamically allocate a separate instance for each thread:
for (i = 0; i < threadnum; i++) {
struct flood_data *ddosData = calloc(1, sizeof(*ddosData));
ddosData->url = url;
ddosData->proxy = getProxy();
pthread_create(&threads[i], NULL, flood, ddosData);
}
...
void *flood(void *structPointer) {
struct flood_data *data = structPointer;
char *bootable = data->url;
char *proxy = data->proxy;
free(data);
...
}
As pointed out in the comments, you also need to check your system calls for failure. You should validate that all of your calls to fopen() are succeeding, as you could very well be hitting the maximum number of file descriptors open in your process. Rather than opening up a file to /dev/null, why don't you just set a no-op write function with the CURLOPT_WRITEFUNCTION option?
static size_t noop_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
// Do nothing
return size * nmemb;
}
...
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &noop_write_callback);
// No need to call fopen("/dev/null") or set CURLOPT_WRITEDATA now
This question already has answers here:
Bad permissions for mapped region [duplicate]
(2 answers)
Closed 9 years ago.
My function should print out letters which are more than once in string. I have no idea why I get an empty output, or my program 'stops working'.
#include <string.h>
#include <stdio.h>
void funkcja3 (char []);
int main()
{
funkcja3("napnapnaaw");
return 0;
}
void funkcja3 (char napis[])
{
int i=0,j;
for(;i<strlen(napis);i++)
{
if((napis[i]>='a')&&(napis[i]<='z'))
{
int n=0;
for(j=i+1;j<strlen(napis);j++)
{
if(napis[i]==napis[j])
{
n++;
napis[j]=' ';
}
}
if(n>0)
{
printf("%c ", napis[i]);
}
}
}
}
You need to pass a modifiable string:
int main()
{
char str[] = "napnapnaaw";
funkcja3(str);
return 0;
}
This is not a direct answer to your question, but if you just want to print out all the non-capital letters that appear more than once in a given string, then you can just use a histogram (symbol-counting) instead:
void funkcja3(char napis[])
{
int histogram['z'-'a'+1] = {0};
for (int i=0; napis[i]!=0; i++)
{
if ('a' <= napis[i] && napis[i] <= 'z')
histogram[napis[i]-'a']++;
}
for (int i=0; i<'z'-'a'+1; i++)
{
if (histogram[i] > 1)
printf("%c ",'a'+i);
}
}
BTW, histogram = the number of occurrences of each symbol in the data.
When I run your program on my machine (Ubuntu, gcc 4.6), I get a segmentation fault and a core dump. Giving the program and the core dump to gdb and doing a backtrace gives
$ gdb a.out core
Core was generated by `/tmp/a.out'.
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004005a2 in funkcja3 (napis=0x40072c "napnapnaaw") at a.c:25
25 napis[j]=' ';
(gdb) bt
bt
#0 0x00000000004005a2 in funkcja3 (napis=0x40072c "napnapnaaw") at a.c:25
#1 0x0000000000400520 in main () at a.c:8
This hint brings me to removing line 25 and running the program again
$ a.out
n a p n a a
which shows all characters, which were repeated somewhere later in the string.
When you call funkcja3, you're calling it with a string literal. This string literal is at a memory location that isn't modifiable, so the call to napid[j] = ' ' should fail (and does so when I copy your example in to visual studio 2013). What you need to do is either A: use std::string (or another string implementation) or B: make a copy of the string in the function, examine it, and then delete the copy when done. Either way, you probably shouldn't be modifying the original string going in to the function. It's generally bad practice to modify objects passed in to a function unless the function absolutely has to do so.
There are some other ways of completing this task as well, such as an array of 26 shorts to hold the counts for each character. Make those counts and then print out any character that has more then 1.
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Please help me. I can't figure out why I get a core dumped when I run this program. Before returning anything I can print all_albums_p just fine. Why am I getting core dumped?
#include "music_server.h"
struct album_ {
int num_tracks;
char **tracks;
int **playlist_hits;
};
typedef struct album_ album;
album *parse_album(FILE *album_file,int *number_of_albums){
int number_of_album,number_of_tracks,number_of_charaters;
int i,j;
char dummy_space;
int *p;
fscanf(album_file,"%d", &number_of_album);
*number_of_albums = number_of_album;
album *all_albums_p = (album *)malloc(sizeof(album)*number_of_album);
for(j=0;j<number_of_album;j++){
fscanf(album_file,"%d", &all_albums_p[j].num_tracks);
all_albums_p[j].tracks = calloc(all_albums_p[j].num_tracks,sizeof(char));
all_albums_p[j].playlist_hits = calloc(all_albums_p[j].num_tracks,sizeof(int));
/*Line 27*/ for(i=0;i<all_albums_p[j].num_tracks;i++){
fscanf(album_file,"%d", &number_of_charaters);
all_albums_p[j].tracks[i] = (char *)calloc(number_of_charaters+1,sizeof(char));
all_albums_p[j].playlist_hits[i] = (int *)malloc(sizeof(int));
all_albums_p[j].playlist_hits[i] = 0;
fscanf(album_file," ",dummy_space);
fscanf(album_file, "%[^\n]s", all_albums_p[j].tracks[i]);
}
}
return all_albums_p;
}
main(int argc, char *argv[]){
int i,j;
int *number_of_albums,*number_of_tracks,a;
a=0;
number_of_albums = &a;
album *all_tracks_ptr;
album_file = fopen(argv[1],"r");
transaction_file = fopen(argv[2],"r");
if((album_file == NULL) || (transaction_file == NULL)){
printf("Either %s or %s could not be open");
}else{
all_tracks_ptr = parse_album(album_file,number_of_albums);
int number_of_tracks[*number_of_albums];
}
}
errors:
Bus Error (core dumped)
(gdb) bt
#0 0xff277c9c in _smalloc () from /lib/libc.so.1
#1 0xff277d10 in malloc () from /lib/libc.so.1
#2 0xff263830 in calloc () from /lib/libc.so.1
#3 0x00010dd8 in parse_album (album_file=0xff3675bc,
number_of_albums=0xffbff894) at functions.c:27
#4 0x00010b80 in main (argc=3, argv=0xffbff90c) at project3.c:19
You should allocate sizeof(char*) below instead of sizeof(char)
all_albums_p[j].tracks = alloc(all_albums_p[j].num_tracks,sizeof(char*));
Since that looks like a Unix message ("Bus Error (core dumped)) I will assume you are using some flavor of Unix.
So, compile your program with debugging info output turned on and with optimization turned off. If you're using gcc or something gcc-compatible, that would be the -g -O0 command line options.
Then run your program and have it crash. Locate the core dump (I'll call it corefile in this example) and then type:
gdb programname corefile
Then when you get the gdb prompt, type bt (for backtrace) to see the program's stackframe. That will tell you where the program crashed and you can examine that part of your program more closely.
Update:
I think your problem is here:
all_albums_p[j].tracks = calloc(all_albums_p[j].num_tracks,sizeof(char));
album.tracks is defined as char**. However, what you're assigning to all_albums_p[j].tracks is a block of memory the size of num_tracks char. You need to assign to it a block of memory big enough to hold num_tracks char *. So you probably need to change the line to:
all_albums_p[j].tracks = (char **) calloc(all_albums_p[j].num_tracks,sizeof(char *));
Use a debugger or valgrind and figure out what line the problem is occurring on. Then you will know what part of your code is bad.