As stated on the topic, i'm using objcopy to load SDL_Image images with MinGW over Eclipse Helios for windows.
I'm using the command: objcopy --input-target binary --output-target pei-i386 --binary-architecture i386 Lilothyn.jpg Lilothyn.o
That results in the file:
Lilothyn.o: file format pei-i386
Lilothyn.o
architecture: i386, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x00000000
Characteristics 0x305
relocations stripped
line numbers stripped
32 bit words
debugging information removed
Time/Date Thu Jan 01 00:00:00 1970
Magic 0000
MajorLinkerVersion 0
MinorLinkerVersion 0
SizeOfCode 00000000
SizeOfInitializedData 00000000
SizeOfUninitializedData 00000000
AddressOfEntryPoint 00000000
BaseOfCode 00000000
BaseOfData 00000000
ImageBase 00000000
SectionAlignment 00000000
FileAlignment 00000000
MajorOSystemVersion 0
MinorOSystemVersion 0
MajorImageVersion 0
MinorImageVersion 0
MajorSubsystemVersion 0
MinorSubsystemVersion 0
Win32Version 00000000
SizeOfImage 00000000
SizeOfHeaders 00000000
CheckSum 00000000
Subsystem 00000000 (unspecified)
DllCharacteristics 00000000
SizeOfStackReserve 00000000
SizeOfStackCommit 00000000
SizeOfHeapReserve 00000000
SizeOfHeapCommit 00000000
LoaderFlags 00000000
NumberOfRvaAndSizes 00000000
The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00000000 00000000 Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 00000000 00000000 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00000000 00000000 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 CLR Runtime Header
Entry f 00000000 00000000 Reserved
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 000024fb 00000000 00000000 000000c0 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _binary_Lilothyn_jpg_start
[ 1](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000024fb _binary_Lilothyn_jpg_end
[ 2](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000024fb _binary_Lilothyn_jpg_size
... and the other:
Tommy.o: file format pei-i386
Tommy.o
architecture: i386, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x00000000
Characteristics 0x305
relocations stripped
line numbers stripped
32 bit words
debugging information removed
Time/Date Thu Jan 01 00:00:00 1970
Magic 0000
MajorLinkerVersion 0
MinorLinkerVersion 0
SizeOfCode 00000000
SizeOfInitializedData 00000000
SizeOfUninitializedData 00000000
AddressOfEntryPoint 00000000
BaseOfCode 00000000
BaseOfData 00000000
ImageBase 00000000
SectionAlignment 00000000
FileAlignment 00000000
MajorOSystemVersion 0
MinorOSystemVersion 0
MajorImageVersion 0
MinorImageVersion 0
MajorSubsystemVersion 0
MinorSubsystemVersion 0
Win32Version 00000000
SizeOfImage 00000000
SizeOfHeaders 00000000
CheckSum 00000000
Subsystem 00000000 (unspecified)
DllCharacteristics 00000000
SizeOfStackReserve 00000000
SizeOfStackCommit 00000000
SizeOfHeapReserve 00000000
SizeOfHeapCommit 00000000
LoaderFlags 00000000
NumberOfRvaAndSizes 00000000
The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00000000 00000000 Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 00000000 00000000 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00000000 00000000 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 CLR Runtime Header
Entry f 00000000 00000000 Reserved
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 000834fe 00000000 00000000 000000c0 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _binary_Tommy_jpg_start
[ 1](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000834fe _binary_Tommy_jpg_end
[ 2](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000834fe _binary_Tommy_jpg_size
The problem is that this last file (Tommy.o) loads properly, while the 1st file (Lilothyn.o) doesn't. As you can see the two are seemingly similar.
My code is extensive so i'll post the relevant parts only.
Source.cpp:
int displayFillThread(SDL_Renderer *renderer, SDL_Window *window, bool *_end) throw()
{
std::cout << "Thread initializing..." << std::endl;
SDL_Texture *texture = getTextureFromStream(&binary_Lilothyn_jpg_start, binary_Lilothyn_jpg_size, window, renderer);
if (texture == NULL)
{
std::cout << "Thread: Failed to load image - " << SDL_GetError() << std::endl;
return 1;
}
std::cout << "Thread initialized!" << std::endl;
for(int i= 10; !*_end && i < 400; i+= 100)
for(int j= 10; !*_end && j < 400; j+= 100)
{
SDL_Delay(100);
AddTextureToRederer(renderer, texture, i, j, 100, 100);
SDL_RenderPresent(renderer);
}
return 0;
}
SDL_Texture *getTextureFromStream(char binary[], unsigned int binary_size, SDL_Window *window, SDL_Renderer *renderer) throw()
{
std::cout << "Starting getTextureFromJPEGStream!" << std::endl;
// char* st = loadFileObject(binary_start, binary_end);
SDL_RWops *rw = SDL_RWFromConstMem(binary, binary_size);
std::cout << "rw loaded!" << std::endl;
SDL_Surface *tmpSurf = IMG_Load_RW(rw, 0);
//SDL_Surface *tmpSurf = SDL_CreateRGBSurfaceFrom(Lilothyn_jpg, 123, 102, 24, 96, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
if (tmpSurf != NULL)
{
SDL_Surface *surf = SDL_ConvertSurfaceFormat(tmpSurf, SDL_GetWindowPixelFormat(window), 0);
if (surf != NULL)
{
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf);
SDL_FreeSurface(surf);
std::cout << "tmpSurf loaded!" << std::endl;
return texture;
}//*/
// SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, tmpSurf);
SDL_FreeSurface(tmpSurf);
std::cout << "surf load failed!" << std::endl;
return NULL;
}
std::cout << "tmpSurf load failed!" << std::endl;
return NULL;
}
int main(int argc, char** argv)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cout << "SDL init Error: " << SDL_GetError() << std::endl;
exit(1);
}
SDL_Window *window = SDL_CreateWindow("SDL_Test", 0, 0, _SCREEN_WIDTH_, _SCREEN_HEIGHT_, SDL_WINDOW_OPENGL | SDL_RENDERER_ACCELERATED); // SDL_WINDOW_FULLSCREEN |
if (window == NULL)
{
std::cout << "Window init Error: " << SDL_GetError() << std::endl;
exit(1);
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer == NULL)
{
SDL_ShowSimpleMessageBox(0, "Renderer init error", SDL_GetError(), window);
}
//SDL_Texture *texture = getTextureFromJPEGStream(binary_Tommy_jpg_start, binary_Tommy_jpg_end, binary_Tommy_jpg_size, window, renderer);
SDL_Texture *texture = getTextureFromStream(&binary_Tommy_jpg_start, binary_Tommy_jpg_size, window, renderer);
//getTextureFromImage("Resources/Tommy.jpg", window, renderer);
if (texture == NULL)
{
SDL_ShowSimpleMessageBox(0, "Background Texture init error", SDL_GetError(), window);
return 1;
}
SDL_RenderCopy(renderer, texture, NULL, NULL);
//AddTextureToRederer(renderer, FTex, 10, 10, 100, 100);
SDL_RenderPresent(renderer);
SDL_Event event;
bool _end = false;
std::cout << "Starting Thread!" << std::endl;
std::thread thread1;
try
{
thread1 = std::thread(displayFillThread, renderer, window, &_end);
std::cout << "Thread loaded!" << std::endl;
}
catch(std::exception& e)
{
std::cout << "Thread load failed: " << e.what() << std::endl;
return 1;
}
std::cout << "main while starting!" << std::endl;
while(!_end)
{
//...
Source.h:
#ifndef SOURCE_H_
#define SOURCE_H_
static int _SCREEN_WIDTH_ = 1024;
static int _SCREEN_HEIGHT_ = 800;
extern char binary_Tommy_jpg_start;
extern unsigned int binary_Tommy_jpg_size;
extern char binary_Lilothyn_jpg_start;
extern unsigned int binary_Lilothyn_jpg_size;
int displayFillThread(SDL_Renderer *renderer, SDL_Window *window, bool *_end) throw();
SDL_Texture *getTextureFromStream(char binary[], unsigned int binary_size, SDL_Window *window, SDL_Renderer *renderer) throw();
//...
And the output:
Starting getTextureFromJPEGStream!
rw loaded!
tmpSurf loaded!
Starting Thread!
Thread loaded!
Thread initializing...
main while starting!
Note that it didn't write the second "getTextureFromJPEGStream!" neither did it appear to have thrown an exception.
It compiles with no problems whatsoever so, is it possible that the Lilothyn.o file is being created corrupted? (I have rebuilt it more than once) And/or maybe the linker isn't linking correctly?
While executing, the program simple stops responding after loading the 1st image, while trying to load the 2nd.
Thank you for the replies.
I've solved this now, the problem was the types used on the .o file.
New code is as follows.
Source.h:
extern uint8_t binary_Lilothyn_jpg_start[];
extern uint8_t binary_Lilothyn_jpg_size[];
Source.cpp
SDL_Texture *getTextureFromStream(uint8_t binary[], uint8_t binary_size[], SDL_Window *window, SDL_Renderer *renderer) throw()
{
size_t converted_size = (size_t)((void *)binary_size);
SDL_Surface *tmpSurf = IMG_Load_RW(SDL_RWFromConstMem(binary, converted_size), 0);
if (tmpSurf != NULL)
{
//...
Thanks to all the viewers, I hope this helps!
Related
I have a very old gameserver file for a video-game that became obsolete years ago (more than a decade and a half has passed since then). A lot of clones and reverse-engineered copycats of this engine exist, but nothing will ever be like the real thing, or at least without tons and tons of work (it's a MMORPG server). It's so old that it uses LinuxThreads instead of NPTL, and uses it for its thread-per-connection architecture (up to 1100 simmultaneos connections interacting with a huge 2D tilebased game world).
I was trying to rewrite it from scratch, since it has ancient GCC debug info available, but had to drop it since the amount of work to do was insane. Now I'm trying to inject new functionality into it, but couldn't proggress any further since I don't really understand how I'm supposed to inject into it.
I've tried coding a very simple injector using ptrace, but the server dies because of a segmentation fault (SIGSEGV) and since I can't attach GDB, I don't really know where the crash is happening.
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#define EMPTY_ADDR 0x80EF000UL
const char *SHELLCODE = "\x90\x90\x90\x90\x90\x90\x90\x90";
pid_t GamePID;
void GetGamePID() {
FILE *fp = fopen("/home/bob/lock.pid", "rb");
if (!fp) {
printf(":: [Error] Game not running.\n");
return;
}
fscanf(fp, "%d", &GamePID);
}
int main() {
GetGamePID();
if (!GamePID)
return 0;
if (ptrace(PTRACE_ATTACH, GamePID, NULL, NULL)) {
printf(":: [Error] Cannot attach.\n");
printf(":: # Fail %d: %s.\n", errno, strerror(errno));
return 0;
}
siginfo_t info;
waitid(P_PID, GamePID, &info, WSTOPPED);
printf(":: [Info] Attach on PID %d.\n", GamePID);
struct user_regs_struct oldregs, regs;
if (ptrace(PTRACE_GETREGS, GamePID, NULL, &oldregs)) {
printf(":: [Error] Cannot save registers (Fail %d).\n", errno);
ptrace(PTRACE_DETACH, GamePID, NULL, NULL);
return 1;
}
unsigned long save[2];
save[0] = ptrace(PTRACE_PEEKTEXT, GamePID, (void *)(EMPTY_ADDR), NULL);
save[1] = ptrace(PTRACE_PEEKTEXT, GamePID, (void *)(EMPTY_ADDR + 8UL), NULL);
size_t payload_size = strlen(SHELLCODE);
uint64_t *payload = (uint64_t *)SHELLCODE;
printf("[*] Injecting payload at address 0x%lx.\n", EMPTY_ADDR);
for (size_t i = 0; i < payload_size; i += 8, payload++) {
if (ptrace(PTRACE_POKETEXT, GamePID, EMPTY_ADDR + i, *payload) < 0) {
printf(":: [Error] Failed to PTRACE_POKETEXT: %s\n", strerror(errno));
return 1;
}
}
regs = oldregs;
regs.rip = EMPTY_ADDR;
if (ptrace(PTRACE_SETREGS, GamePID, NULL, ®s)) {
printf(":: [Error] Cannot modify registers.\n");
ptrace(PTRACE_DETACH, GamePID, NULL, NULL);
return 1;
}
if (ptrace(PTRACE_CONT, GamePID, NULL, NULL)) {
printf(":: [Error] Cannot run shellcode.\n");
ptrace(PTRACE_DETACH, GamePID, NULL, NULL);
return 1;
}
waitid(P_PID, GamePID, &info, WSTOPPED);
// I used blank r-xp space but just in case...
if (ptrace(PTRACE_POKETEXT, GamePID, (void *)(EMPTY_ADDR), (void *)save[0]) ||
ptrace(PTRACE_POKETEXT, GamePID, (void *)(EMPTY_ADDR + 8UL), (void *)save[1])) {
printf(":: [Error] Cannot restore origcode.\n");
ptrace(PTRACE_DETACH, GamePID, NULL, NULL);
return 1;
}
if (ptrace(PTRACE_SETREGS, GamePID, NULL, &oldregs)) {
printf(":: [Error] Cannot restore registers.\n");
ptrace(PTRACE_DETACH, GamePID, NULL, NULL);
return 1;
}
if (ptrace(PTRACE_DETACH, GamePID, NULL, NULL)) {
printf(":: [Error] Cannot detach from process.\n");
return 1;
}
puts("[+] Done.");
}
That's how my injector looks like. Strings and whatnot is hardcoded because this is dummy code. Here is /proc/pid/maps output:
08047000-08048000 rwxp 00000000 08:01 549662 /home/bob/bin/game.orig
08048000-08125000 r-xp 00001000 08:01 549662 /home/bob/bin/game.orig
08125000-08129000 rwxp 000dd000 08:01 549662 /home/bob/bin/game.orig
08129000-0eb45000 rwxp 00000000 00:00 0
0f3e2000-14f10000 rwxp 00000000 00:00 0 [heap]
c573f000-f7b69000 rwxp 00000000 00:00 0
f7b6a000-f7b71000 rwxs 00000000 00:01 32821 /SYSV0000271b (deleted)
f7b71000-f7b72000 rwxp 00000000 00:00 0
f7bb5000-f7beb000 rwxp 00000000 00:00 0
f7bec000-f7d3e000 rwxp 00000000 00:00 0
f7d3e000-f7e57000 r-xp 00000000 08:01 1041510 /home/bob/lib/libc.so.6
f7e57000-f7e59000 r-xp 00119000 08:01 1041510 /home/bob/lib/libc.so.6
f7e59000-f7e5b000 rwxp 0011b000 08:01 1041510 /home/bob/lib/libc.so.6
f7e5b000-f7e5d000 rwxp 00000000 00:00 0
f7e5d000-f7e66000 r-xp 00000000 08:01 1041511 /home/bob/lib/libgcc_s.so.1
f7e66000-f7e67000 rwxp 00009000 08:01 1041511 /home/bob/lib/libgcc_s.so.1
f7e67000-f7e68000 rwxp 00000000 00:00 0
f7e68000-f7e8c000 r-xp 00000000 08:01 1041512 /home/bob/lib/libm.so.6
f7e8c000-f7e8d000 r-xp 00023000 08:01 1041512 /home/bob/lib/libm.so.6
f7e8d000-f7e8e000 rwxp 00024000 08:01 1041512 /home/bob/lib/libm.so.6
f7e8e000-f7f3d000 r-xp 00000000 08:01 1041514 /home/bob/lib/libstdc++.so.5
f7f3d000-f7f42000 rwxp 000ae000 08:01 1041514 /home/bob/lib/libstdc++.so.5
f7f42000-f7f47000 rwxp 00000000 00:00 0
f7f47000-f7f56000 r-xp 00000000 08:01 1041513 /home/bob/lib/libpthread.so.0
f7f56000-f7f57000 r-xp 0000e000 08:01 1041513 /home/bob/lib/libpthread.so.0
f7f57000-f7f58000 rwxp 0000f000 08:01 1041513 /home/bob/lib/libpthread.so.0
f7f58000-f7f9b000 rwxp 00000000 00:00 0
f7f9b000-f7f9e000 r--p 00000000 00:00 0 [vvar]
f7f9e000-f7f9f000 r-xp 00000000 00:00 0 [vdso]
f7f9f000-f7fb8000 r-xp 00000000 08:01 1041509 /home/bob/lib/ld-linux.so.2
f7fb8000-f7fb9000 r-xp 00018000 08:01 1041509 /home/bob/lib/ld-linux.so.2
f7fb9000-f7fba000 rwxp 00019000 08:01 1041509 /home/bob/lib/ld-linux.so.2
ff000000-ff001000 ---p 00000000 00:00 0
ff001000-ff200000 rwxp 00000000 00:00 0
ff200000-ff201000 ---p 00000000 00:00 0
ff201000-ff400000 rwxp 00000000 00:00 0
ff400000-ff401000 ---p 00000000 00:00 0
ff401000-ff600000 rwxp 00000000 00:00 0
ff600000-ff601000 ---p 00000000 00:00 0
ff601000-ff800000 rwxp 00000000 00:00 0
fff4b000-fffa2000 rwxp 00000000 00:00 0 [stack]
My server spawns each thread as an independent process, and as you can see I had to use my libraries (/home/bob/lib) copied from and ancient RedHat version which was compatible with the threading model (getpid() returns a different value for each thread).
I would really like to hear some suggestions on how I can inject new code. Is it just as hacky as writing directly to /proc/pid/mem? How would I override a game function (say, HandlePlayerMove) with /proc/pid/mem? Is it possible to inject a shared object using LD_PRELOAD given that it was compiled against a newer version of libc, libm, etc? Is there a way of knowing what's triggering SIGSEGV without ptrace failing?
edit: dummy code typo
I'm currently facing an issue with a vector iterator in C++. The application runs on an ESP8266 NodeMCU microcontroller. As soon as I call the function CWebServer::getAvailableNetworks() (implementation can be found below), the program crashes and I get the following error:
User exception (panic/abort/assert)
Abort called
>>>stack>>>
ctx: cont
sp: 3ffffd10 end: 3fffffc0 offset: 0000
3ffffd10: 00000000 00000000 00000000 00000000
3ffffd20: 000000fe 00000000 00000000 00000000
3ffffd30: 00000000 00000000 00000000 b8b1aabc
3ffffd40: 3ffefd60 3fff44cc 00000000 40205e9c
3ffffd50: 3fff451c 00000001 3fff44fc 4020e7ea
3ffffd60: 00000000 00000000 00000000 4020e7fc
3ffffd70: 00000000 3ffffe0c 00000000 4020e219
3ffffd80: 3ffffe04 00000000 00000000 00000000
3ffffd90: 00000000 00000000 00000000 40226fac
3ffffda0: 00000000 40205e9c 3fff451c 40226fbd
3ffffdb0: 3fff44fc 3fff44cc 3fff44fc 402277d8
3ffffdc0: 00000000 00000000 3fff44fc 4020e224
3ffffdd0: 40000000 00000000 00000000 00000000
3ffffde0: 00000000 00000000 00000000 40226fac
3ffffdf0: 3ffefb6c 40205e9c 3fff451c 40226fbd
3ffffe00: 3fff44fc 4022770c 3fff44fc 40227783
3ffffe10: 3fff451c 00000001 3ffffe80 40209f32
3ffffe20: 3ffe90e4 3fffc200 3ffe90f1 4022f3b3
3ffffe30: 3fff43dc 3ffefa4c 3ffe8a37 4020ca74
3ffffe40: 4020ca68 3ffefa4c 3ffe8a37 40205e9c
3ffffe50: 00000001 3ffffe8c 3ffe90e5 4022f3f6
3ffffe60: 3ffffe80 00000001 3ffefa4c 40205e9c
3ffffe70: 00000001 00000001 3ffefa4c 40209915
3ffffe80: 00000000 00000000 00000000 3fff43e8
3ffffe90: 00000001 00000001 00000020 401009b7
3ffffea0: 3fff3d4c 3fffff00 3ffffee0 40205e9c
3ffffeb0: 00000001 00000001 3fff3c54 4021837a
3ffffec0: 3fffff00 3ffef94c 3fff3c54 401000e1
3ffffed0: 3fff3c54 3ffef94c 3fff3c54 40205ed8
3ffffee0: 3fff3d00 0015001f 8015001f 80fe8614
3ffffef0: 3fff3c54 3ffef94c 3ffef90c 40208526
3fffff00: 3fff3d4c 0015001f 00c6a700 00000000
3fffff10: 807a1200 3fff4400 0000005f 80007641
3fffff20: 3ffef94c 00000001 402183ac 00000001
3fffff30: 00000001 00000000 00001388 4020bb3e
3fffff40: 00000000 3fff43a4 3ffef90c 3ffefac8
3fffff50: 00000001 3ffef930 3ffef90c 402093ec
3fffff60: 40218d50 00000000 00001388 4020ca74
3fffff70: 00000000 3fff43a4 3ffe8a37 4020cd39
3fffff80: 3fffdad0 00000000 3ffefa88 402094b0
3fffff90: 3fffdad0 00000000 3ffefa88 4020a140
3fffffa0: feefeffe feefeffe 3ffefa88 4020e454
3fffffb0: feefeffe feefeffe 3ffe8614 40100cb9
<<<stack<<<
ets Jan 8 2013,rst cause:1, boot mode:(3,7)
load 0x4010f000, len 3456, room 16
tail 0
chksum 0x84
csum 0x84
va5432625
~ld
Here is the function that causes the problem ():
void CWebServer::getAvailableNetworks()
{
Serial.println("Get network scan result.");
bool statusSend = false;
try
{
std::string output = "{\"networks\":";
std::vector<sWiFi_Data*> data = CWiFiConnection::getAvailableNetworks();
if(data.size() <= 0)
{
output += "{}";
}
for(std::vector<sWiFi_Data*>::iterator it = data.begin(); it != data.end(); ++it)
{
// This line is for testing. Later on the JSON output will be calculated here from the Vector.
Serial.println(((*it)->SSID).c_str());
}
output += "}";
statusSend = true;
server.send(200, "application/json", output.c_str());
} catch(ScanException& e)
{
statusSend = true;
server.send(425);
} catch(std::exception e)
{
statusSend = true;
server.send(500);
Serial.println();
Serial.println("Unknown Exception while getting the network data:");
Serial.println(e.what());
Serial.println();
}
if(!statusSend) server.send(500);
}
This function should send the results of a network scan to the client. The network scan is simply done by calling the function WiFi.scanNetworks(true, true); which is part of the ESP8266WiFi.
The problem is caused by the line Serial.println(((*it)->SSID).c_str());
As soon as the program gets to this point, the error will show up and the program crashes. If I just delete this line and don't touch the vector at all, everything runs fine. So I assume that the vector iterator is the bad guy here.
Just for completence: as you can see the vector stores pointer to structs of type "sWiFi_Data".
This struct is defined in another class (the class that handles the WiFi connection) and it looks like this:
struct sWiFi_Data
{
std::string SSID;
std::string BSSID;
int32_t RSSI;
uint8_t channel;
uint8_t encryptionType;
bool isHidden;
};
As you may have noticed inside the CWebServer::getAvailableNetworks() function, the vector is the result of another function ( CWiFiConnection::getAvailableNetworks(); ). This function is inside the CWiFiConnection class. It looks like this:
std::vector<sWiFi_Data*> CWiFiConnection::getAvailableNetworks()
{
std::vector<sWiFi_Data*> data;
int8_t n = WiFi.scanComplete();
if(n == -1) throw ScanException("Warning: Trying to access network scan data while scan is not completed yet.");
if(n == -2) throw ScanException("Warning: Trying to access network scan, but scan was never triggered.");
if(n >= 0)
{
for(int i = 0; i < n; i++)
{
uint8_t encrytptionType = 0;
switch(WiFi.encryptionType(i)) {
case ENC_TYPE_NONE:
encrytptionType = 1; // None, Open Network
case ENC_TYPE_WEP:
encrytptionType = 2; // WEP
case ENC_TYPE_TKIP:
encrytptionType = 3; // WPA
case ENC_TYPE_CCMP:
encrytptionType = 4; // WPA 2
case ENC_TYPE_AUTO:
encrytptionType = 5; // Auto
default:
encrytptionType = 0; // Unknown
}
sWiFi_Data wifiData;
wifiData.SSID = WiFi.SSID(i).c_str();
wifiData.BSSID = WiFi.BSSIDstr(i).c_str();
wifiData.RSSI = WiFi.RSSI(i);
wifiData.channel = WiFi.channel(i);
wifiData.encryptionType = encrytptionType;
wifiData.isHidden = WiFi.isHidden(i);
data.push_back(&wifiData);
}
WiFi.scanDelete();
return data;
} else
{
throw ScanException("Warning: No networks found.");
}
}
By the way: the ScanException is just a generic exception that I wrote. Nothing fancy so I don't think that I would need to include the code here.
And just to clarify things, the procedure of communication looks like this:
Client send request to scan networks.
Server just calls the method: WiFi.scanNetworks(true, true); (Parameters: bool async, bool showHidden)
Because the scan is asynchronous, the client checks the result by sending a request to the server.
The server always responds to these requests by calling the CWebServer::getAvailableNetworks() function (our problem function).
In theory this function should reply with a code 425 ("not ready yet") if the result isn't there yet and should send the data of all available networks as a JSON if the scan is finished (this will be implemented where the line Serial.println(((*it)->SSID).c_str()); currently is.
By the way: I also tried to just output the vector's size inside the console. This works fine. So there are definitely values inside the vector.
Hope that anyone can help me out here. Thanks a lot.
Jannis
ps.: A documentation with examples for the network scan on an ESP8266 can be found here: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html
This line: data.push_back(&wifiData); stores the address of a temporary object wifiData which will be destroyed once the scope, i.e the enclosing for-loop iteration, is exited.
When you then later access any of these addresses it will (probably) cause a seg fault (if you are lucky).
Instead of having a std::vector<sWiFi_Data*> better use a std::vector<sWiFi_Data>
I am new to mmap and still learning it . Based on my understanding i have created class for mmap which will be used to map a file in memory . The entire class is working fine but problem is coming when destructor is called ..the problem is segmentation fault or invalid pointer error is coming at the end of main function ...I have posted code of my class and main function which is using that class ...
Map.h
class MapData
{
public :
MapData();
~MapData();
MapData(char []);
bool OPEN();
void fnClose();
long fnGetSize();
char * fnGetFileRef();
char * ReadNextData(int );
private :
char * ptrRecord;
char ptrFileNm[250+1];
int fd;
struct stat sbuf;
bool bSuccess;
long sTotalSize;
char acData[2000+1];
long lCurrRead;
};
MapData.cpp
MapData::MapData()
{
}
MapData::~MapData()
{
printf("Inside MADATA Destructor \n ");
}
MapData::MapData(char acInput[])
{
strcpy(ptrFileNm,acInput);
sTotalSize=0;
lCurrRead=0;
bSuccess=false;
}
bool MapData::OPEN()
{
// if failed return false flg
if ((fd = open(ptrFileNm, O_RDONLY)) == -1) {
return bSuccess;
}
if (stat(ptrFileNm, &sbuf) == -1) {
return bSuccess;
}
// copy in local variable
sTotalSize = sbuf.st_size;
ptrRecord = (char * )mmap( (caddr_t)0, sTotalSize, PROT_READ, MAP_SHARED, fd, 0) ;
if (ptrRecord == (char *)(caddr_t)(-1) ) {
perror("Fail to Map Data ");
return bSuccess;
}
else
{
printf("Successfully Map Data***[%ld] \n",sTotalSize);
bSuccess=true;
}
return bSuccess;
}
char * MapData::fnGetFileRef()
{
return ptrRecord;
}
char * MapData::ReadNextData(int iX)
{
if((lCurrRead+iX)<sTotalSize)
{
memset(acData,0x00,sizeof(acData));
strncpy(acData,ptrRecord+lCurrRead,iX);
acData[iX+1]='\0';
lCurrRead+=iX;
}else{
strcpy(acData,"ZZZ");
}
return acData;
}
long MapData::fnGetSize()
{
return sTotalSize;
}
void MapData::fnClose()
{
// Don't forget to free the mmapped memory
if(munmap(ptrRecord, sTotalSize) == -1)
{
close(fd);
perror("Error un-mmapping the file");
exit(EXIT_FAILURE);
}
// Un-mmaping doesn't close the file, so we still need to do that.
close(fd);
printf("CLOSED SUCCESSFULLY \n ");
}
Main.cpp
int main()
{
char acFileNm[500+1];
MEMSET(acFileNm); // clean the variable
// file name to be read
strcpy(acFileNm,"ABDFILE.txt");
long lProcCnt=0; // no of byte read by program
char acLine[MAX_LINE_LENGTH+1]; // hold current read line
bool bFlag=true; // main flag
DEBUG_PRINT("File to be processed:%s \n",acFileNm);
// create object of mmap
MapData * pt1 = NULL;
pt1 = new MapData(acFileNm);
if(!pt1)
{
cout<<"Error creating object so quit ..."<<endl;
return 0 ;
}
auto_ptr<MapData> ptrMap( pt1 ); // pass ownership to auto deletor to delete memory
DEBUG_PRINT("STEP1:%s \n","OBJECT CREATION FOR FILE MAPPED IN MEMORY");
// try to open the file
if(ptrMap->OPEN())
{
// on success..get pointer to first char of file
char * ptrData = ptrMap->fnGetFileRef();
long lCompSize=ptrMap->fnGetSize(); // total no of bytes = fiexed line size * no of row + (no of row * EOL)
short int iEOL=0;
// logic to identify file generated on ewhich OS
if( (*(ptrData+MAX_LINE_LENGTH) == '\r') && (*(ptrData+MAX_LINE_LENGTH+1) == '\n'))
{
// DOS format CRLF
iEOL = 2;
}else if(*(ptrData+MAX_LINE_LENGTH) == '\n'){
// Unix format LF
iEOL = 1;
}
DEBUG_PRINT("STEP2: SIZEOFFILE%ld FILESYSTEM FORMAT:%d \n",lCompSize,iEOL);
// here read till it reaches maximum limit of file
while(lProcCnt<lCompSize)
{
//DEBUG_PRINT("PROC COUNTER[%ld] MAX_COUNTER[%ld] \n",lProcCnt,lCompSize);
lProcCnt+=MAX_LINE_LENGTH+iEOL; // increement no of bytes read at initial
MEMSET(acLine);
strncpy(acLine,ptrData+lProcCnt,MAX_LINE_LENGTH); // read line
acLine[MAX_LINE_LENGTH+1]='\0';
// process the line :function is called here to process the line
}
}else{
DEBUG_PRINT("MAP DATA FAILED OF FILE[%s] \n",acFileNm);
bFlag=false;
}
// at the end check if all the controls are matched
if(bFlag)
DEBUG_PRINT("END OF FILE PROCESSING SUCCESS \n");
else
DEBUG_PRINT("END OF FILE PROCESSING FAILED \n");
// close the memory map
ptrMap->fnClose();
MapData * ptr5 = ptrMap.release(); // release the ownership
delete ptr5; **// segmentation fault comes here ...**
}
Please suggest me where i am going wrong since gdb is also not helping ...detailed explanation will be good for me to understand ...
Stacktrace generated by gdb:
*** glibc detected *** DemoMap: free(): invalid pointer: 0x0804c000 ***
======= Backtrace: =========
/lib/libc.so.6[0x9bbc81]
/lib/libc.so.6[0x9be562]
/usr/lib/libstdc++.so.6(_ZdlPv+0x22)[0x544552]
DemoMap[0x80491e6]
/lib/libc.so.6(__libc_start_main+0xe6)[0x961d36]
DemoMap[0x8048d91]
======= Memory map: ========
00110000-00111000 r-xp 00000000 00:00 0 [vdso]
0044c000-00469000 r-xp 00000000 08:03 1237 /lib/libgcc_s-4.4.7-20120601.so.1
00469000-0046a000 rw-p 0001d000 08:03 1237 /lib/libgcc_s-4.4.7-20120601.so.1
00495000-00576000 r-xp 00000000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
00576000-0057a000 r--p 000e0000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
0057a000-0057c000 rw-p 000e4000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
0057c000-00582000 rw-p 00000000 00:00 0
00929000-00947000 r-xp 00000000 08:03 1065 /lib/ld-2.12.so
00947000-00948000 r--p 0001d000 08:03 1065 /lib/ld-2.12.so
00948000-00949000 rw-p 0001e000 08:03 1065 /lib/ld-2.12.so
0094b000-00adb000 r-xp 00000000 08:03 1067 /lib/libc-2.12.so
00adb000-00adc000 ---p 00190000 08:03 1067 /lib/libc-2.12.so
00adc000-00ade000 r--p 00190000 08:03 1067 /lib/libc-2.12.so
00ade000-00adf000 rw-p 00192000 08:03 1067 /lib/libc-2.12.so
00adf000-00ae2000 rw-p 00000000 00:00 0
00b29000-00b51000 r-xp 00000000 08:03 1211 /lib/libm-2.12.so
00b51000-00b52000 r--p 00027000 08:03 1211 /lib/libm-2.12.so
00b52000-00b53000 rw-p 00028000 08:03 1211 /lib/libm-2.12.so
08048000-0804b000 r-xp 00000000 08:08 2883976 DemoMap
0804b000-0804c000 rw-p 00002000 08:08 2883976 DemoMap
0804c000-0806d000 rw-p 00000000 00:00 0 [heap]
b7e00000-b7e21000 rw-p 00000000 00:00 0
b7e21000-b7f00000 ---p 00000000 00:00 0
b7f9b000-b7fe5000 r--s 00000000 08:08 4326707 ABCDEF.TXT
b7fe5000-b7fe8000 rw-p 00000000 00:00 0
b7ffd000-b8000000 rw-p 00000000 00:00 0
bffeb000-c0000000 rw-p 00000000 00:00 0 [stack]
may be here.
char ptrFileNm[250+1];
char acFileNm[500+1];
MapData::MapData(char acInput[])
{
strcpy(ptrFileNm,acInput);//segmentation fault
sTotalSize=0;
lCurrRead=0;
bSuccess=false;
}
I have one problem. I am trying to get stack offset range from /proc/self/maps pseudofile. But I have sometime weird things.
Here is my code
fp = fopen("/proc/self/maps", "r");
if (fp == NULL) {
perror("Error opening file");
return NULL;
}
while (fgets(line, 2048, fp) != NULL) {
if (strstr(line, "stack") != NULL) {
printf("%s", line);
}
}
If you start the programm with one or multiple thread you can view this pseudo file and get something like this
7f20423a6000-7f2042ba6000 rw-p 00000000 00:00 0 [stack:3936]
7fffbe95e000-7fffbe97f000 rw-p 00000000 00:00 0 [stack]
the first line here is stack of thread , the second line is the stack of the process.
But the problem is that sometimes I cannot get stack of thread. It can be from the first time or appear on some next execution so it is not determined. On some distos it doesn't show stack of thread at all, I don't think the problem is in different implementation of pseudo file in distros but in something other.
Please help to solve this problem
EDIT
I actually call this function inside thread , so I create thread through pthread_create(&tid, NULL, proc_stack, NULL);I have been also thinking about this. Maybe it needs some time to update this pseudofile after thread start, this is only one reason I see here.
EDIT2
I've tried to call sleep forcely , but this didn't help, but the most weird is that on one distro it shows thread stack, on another doesn't.
On my system Your program also dosn't show second stack segment, but it seems 5 segments are allocated above [heap] and one of them is used for thread stack (local variables of proc_stack() are stored in this segment).
Code I used to check for it (test.c):
#include <stdio.h>
#include <string.h>
#include <pthread.h>
void* proc_stack(void* p){
FILE *fp;
char line[2048];
fp = fopen("/proc/self/maps", "r");
if (fp == NULL) {
perror("Error opening file");
return NULL;
}
while (fgets(line, 2048, fp) != NULL) {
// if (strstr(line, "stack") != NULL) {
printf("%s", line);
// }
}
printf("addr = %p %p\n", &fp, &line);
return NULL;
}
int main(){
pthread_t tid;
void *rv;
proc_stack( NULL );
puts("main");
pthread_create( &tid, NULL, proc_stack, NULL );
pthread_join( tid, &rv );
return 0;
}
Compiled with gcc -Wall test.c -pthread. Results (some lines removed):
...
01933000-01954000 rw-p 00000000 00:00 0 [heap]
...
7fff75be3000-7fff75c04000 rw-p 00000000 00:00 0 [stack]
7fff75d97000-7fff75d98000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
addr = 0x7fff75c00e68 0x7fff75c00e70
main
...
01933000-01954000 rw-p 00000000 00:00 0 [heap]
7f3be0000000-7f3be0021000 rw-p 00000000 00:00 0
7f3be0021000-7f3be4000000 ---p 00000000 00:00 0
7f3be6b79000-7f3be6b7a000 rw-p 00000000 00:00 0
7f3be6b7a000-7f3be6b7b000 ---p 00000000 00:00 0
7f3be6b7b000-7f3be737b000 rw-p 00000000 00:00 0
...
7fff75be3000-7fff75c04000 rw-p 00000000 00:00 0 [stack]
7fff75d97000-7fff75d98000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
addr = 0x7f3be73796c8 0x7f3be73796d0
i have the following main code:
#include "ComHandler.h"
#include "socketMessage.h"
#define THIS_IP "localhost"
#define C_PORT 32456
#define S_PORT 25465
#define S_PORT_UDP 22548
int main(int argc, char* argv[]) {
conOptions opts;
strncpy(opts.password, "PASS", sizeof("PASS"));
opts.retryQty = 5;
opts.timeout = 300;
char dir[INET6_ADDRSTRLEN];
strncpy(dir, THIS_IP, sizeof(THIS_IP));
if (argv[1][0] == 'C') {
opts.connType = CLIENT_HANDLER;
opts.thisID = 2;
ComHandler comH(opts);
char buffer[10];
strncpy(buffer, "Testing", 10);
int rtnValue = comH.sendMsg(buffer, 10, 1, TCP_C);
std::cout << "Returned Value: " << rtnValue << std::endl;
} else {
opts.connType = SERVER_HANDLER;
opts.thisID = 1;
ComHandler comH(opts);
comH.addConnectionData(2, dir, C_PORT);
comH.addConnectionData(comH.getID(), dir, S_PORT);
char rcvdTxt[MINIDATA_DATA_SIZE];
comH.receiveMsg(rcvdTxt, MINIDATA_DATA_SIZE, 2, TCP_C);
std::cout << "Received: " << rcvdTxt << std::endl;
comH.closeCommunications();
}
}
The code is for testing my communication platform. The platform works well, but the problem appears when the messages are received by the Handler (ComHandler). When i call the method "receiveMsg" from ComHandler, i get a "stack smashing detected" in the "return" of the method.
This is the "ComHandler" class:
#ifndef COMHANDLER_H_
#define COMHANDLER_H_
#include "Constants.h"
#include "ComConstants.h"
#include "DataLogger.h"
#include <list>
#include <math.h>
#define CLIENT_HANDLER 1
#define SERVER_HANDLER 2
#define COMMENT_LINE '#'
#define TXT_SEPARATOR ';'
#define MINIDATA_DATA_SIZE (COMDATA_MAX_SIZE - 4* sizeof(int))
enum CON_TYPE {
TCP_C, UDP_C
};
#pragma pack(push)
#pragma pack(1)
typedef struct {
int totalPackets;
int sequenceNumber;
int sequenceID;
int dataSize;
char data[MINIDATA_DATA_SIZE];
} miniData;
#pragma pack(pop)
typedef struct connectionOptions {
unsigned int timeout;
unsigned int retryQty;
id_t thisID;
char password[PASSWORD_MAX_SIZE];
int connType;
connectionOptions() :
timeout(CON_TIMEOUT), retryQty(SOCKET_RETRIES), connType(
SERVER_HANDLER) {
memset(password, 0, PASSWORD_MAX_SIZE);
}
connectionOptions(connectionOptions& opt) {
timeout = opt.timeout;
retryQty = opt.retryQty;
thisID = opt.thisID;
connType = opt.connType;
memcpy(password, opt.password, PASSWORD_MAX_SIZE);
}
} conOptions;
class ComHandler {
private:
int dataForwarder_ReceiverMsgQueue;
int dataForwarder_SenderMsgQueue;
conOptions opts;
int sequenceID;
Semaphore ch_mux;
SharedMemory<comHandlerGlOp> ch_shm;
void cpyMiniData(miniData* to, miniData* from);
void createIPCs();
public:
ComHandler();
ComHandler(conOptions options);
ComHandler(id_t thisID);
virtual ~ComHandler();
int receiveMsg(char* buffer, int bufferSize, id_t originID,
CON_TYPE type = TCP_C);
int sendMsg(char* buffer, std::size_t bufferSize, id_t destinationID,
CON_TYPE type = TCP_C);
void configListenersData(char addr[INET6_ADDRSTRLEN], int port,
CON_TYPE type);
void addConnectionData(id_t id, char addr[INET6_ADDRSTRLEN], int port);
void addConnectionData(const char* file);
void modifyConnectionData(id_t id, char addr[INET6_ADDRSTRLEN], int port);
void removeConnectionData(id_t id);
int getID();
void closeCommunications();
};
#endif /* COMHANDLER_H_ */
The comData structure:
typedef struct {
long type;
int requestType;
char destination[INET6_ADDRSTRLEN];
char origin[INET6_ADDRSTRLEN];
id_t originID;
id_t destinationID;
int port;
pid_t senderPid;
pid_t originPid;
char data[COMDATA_MAX_SIZE];
} comData;
And the method with the problem:
int ComHandler::receiveMsg(char* buffer, int bufferSize, id_t originID,
CON_TYPE type) {
comData aux;
aux.type = DATA_RECEIVE;
int qtyReceived = 0;
if (originID != ANY_MSG_ORIGIN) {
if (type == TCP_C)
aux.requestType = RECEIVE_DATA_FROM_DESTINATION_TCP;
else
aux.requestType = RECEIVE_DATA_FROM_DESTINATION_UDP;
} else {
if (type == TCP_C)
aux.requestType = RECEIVE_ANY_DATA_TCP;
else
aux.requestType = RECEIVE_ANY_DATA_UDP;
}
aux.originID = originID;
aux.senderPid = getpid();
aux.originPid = getpid();
msgsnd(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), 0);
msgrcv(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), getpid(), 0);
/* More Code */
return qtyReceived;
}
The stack smashing error appears after "return qtyReceived;" is called. And the /* More Code */ in the middle is the non important code, because if a delete that part, the stack smashing stills appears.
After much debugging i found that the smashing appears if i call:
`msgrcv(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), getpid(), 0);`
if i comment that line, i don't get the error.
Also with the debugger, i was able to see that the messages from the queue arrive with good format and size, exactly as they should.
The console output is:
*** stack smashing detected ***: /media/blackhole/workspace/Final/bin/ComTest terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb7df88d5]
/lib/i386-linux-gnu/libc.so.6(+0xe7887)[0xb7df8887]
/media/blackhole/workspace/Final/bin/ComTest[0x804dc6b]
/media/blackhole/workspace/Final/bin/ComTest[0x804a002]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb7d2a113]
/media/blackhole/workspace/Final/bin/ComTest[0x8049d11]
======= Memory map: ========
08048000-08054000 r-xp 00000000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08054000-08055000 r--p 0000b000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08055000-08056000 rw-p 0000c000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08056000-08077000 rw-p 00000000 00:00 0 [heap]
b7d0f000-b7d11000 rw-p 00000000 00:00 0
b7d11000-b7e87000 r-xp 00000000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e87000-b7e89000 r--p 00176000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e89000-b7e8a000 rw-p 00178000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e8a000-b7e8d000 rw-p 00000000 00:00 0
b7e8d000-b7ea9000 r-xp 00000000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7ea9000-b7eaa000 r--p 0001b000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7eaa000-b7eab000 rw-p 0001c000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7eab000-b7eac000 rw-p 00000000 00:00 0
b7eac000-b7ed4000 r-xp 00000000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed4000-b7ed5000 r--p 00028000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed5000-b7ed6000 rw-p 00029000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed6000-b7fb4000 r-xp 00000000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb4000-b7fb5000 ---p 000de000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb5000-b7fb9000 r--p 000de000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb9000-b7fba000 rw-p 000e2000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fba000-b7fc1000 rw-p 00000000 00:00 0
b7fdc000-b7fdd000 rw-s 00000000 00:04 163119127 /SYSV02056f32 (deleted)
b7fdd000-b7fdf000 rw-p 00000000 00:00 0
b7fdf000-b7fe0000 r-xp 00000000 00:00 0 [vdso]
b7fe0000-b7ffe000 r-xp 00000000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
b7ffe000-b7fff000 r--p 0001d000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
b7fff000-b8000000 rw-p 0001e000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]
So, any ideas? If you need something about the code, just ask me.
According to this, the msgsz parameter of msgrcv() should be the size of the mtext member of the mymsg struct:
struct mymsg {
long int mtype; /* message type */
char mtext[1]; /* message text */
}
The problem is that you include the size of the mtype member (4 bytes) so msgrcv() writes four bytes past the end of your struct which trashes the stack.