I am getting a crash when trying to use initstate_r:
(gdb) run
Starting program: /home/user/test.out
Program received signal SIGSEGV, Segmentation fault.
0x40052d00 in initstate_r () from /lib/libc.so.6
The code:
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define STATELEN 256 /* random number state buffer */
main()
{
char randomStateBuffer[STATELEN];
struct random_data randData;
printf("Before initstate");
/* seed the random number generator */
initstate_r (time(NULL), (char *)&randomStateBuffer, STATELEN,
(struct random_data *)&randData);
printf("initstate done");
}
I have tried compiling this in both gcc 3.3.6 and 4.3.3 and both have the crash.
Try zeroing out randData struct before calling initstate_r().
memset( &randData, 0, sizeof( random_data ) );
(Taking a cue from this page: http://sourceware.org/bugzilla/show_bug.cgi?id=3662)
This question looks amazingly similar to:
http://www.linuxquestions.org/questions/programming-9/crash-in-initstate_r-408757/
Also, see:
http://lists.debian.org/debian-glibc/2006/01/msg00037.html
and:
http://lists.debian.org/debian-glibc/2005/08/msg00492.html
The man page for that function is hard to understand, but it seems maybe rand_data should be initialized before passing to initstate_r
Looking at the function signature the second argument is just a char*. Take the address-of operator off randomStateBuffer.
initstate_r (time(NULL), randomStateBuffer, STATELEN,
(struct random_data *)&randData);
?
I've experienced the same difficulties and it worked by 0-ing out both state and rand_data, and in your case, removing the & in front of the buffer:
char randomStateBuffer[STATELEN];
struct random_data randData;
memset(randomStateBuffer, 0, sizeof(randomStateBuffer));
memset(&randData, 0, sizeof(struct random_data));
initstate_r(time(NULL), randomStateBuffer,sizeof(randomStateBuffer), &randData);
worked for me.
Related
I tried to mimic the way jemalloc replaces ptmalloc by replacing malloc myself, and the replacement resulted in a direct segment error
code1.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
void *ptr = malloc(10);
printf("%p\n", ptr);
return EXIT_SUCCESS;
}
code2.c:
#include <stdlib.h>
#include <stdint.h>
void *malloc(size_t size)
{
return (void *)10;
}
Compile instructions
gcc -c code2.c
ar r libcode2.a code2.o
gcc code1.c -L. -lcode2 -g
gdb
Breakpoint 1, main (argc=1, argv=0x7fffffffe318) at code1.c
17 void *ptr = malloc(10);
(gdb) s
18 printf("%p\n", ptr);
(gdb) p ptr
$1 = (void *) 0xa
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e46658 in __GI__IO_file_overflow () from /lib64/libc.so.6
the replacement resulted in a direct segment error code1.c
If you replace malloc with a non-functional variant, you better not call any libc functions which may use malloc in their implementation.
Here you called printf, which itself uses malloc internally. Use GDB where command to observe where the crash happened.
I am actually surprised your program made it as far as reaching main() -- I expected it to crash much earlier (there are 1000s of instruction executed long before main is reached).
I have been trying to intercept calls to malloc and free, following our textbook (CSAPP book).
I have followed their exact code, and nearly the same code that I found online and I keep getting a segmentation fault. I heard our professor saying something about printf that mallocs and frees memory so I think that this happens because I am intercepting a malloc and since I am using a printf function inside the intercepting function, it will call itself recursively.
However I can't seem to find a solution to solving this problem? Our professor demonstrated that intercepting worked ( he didn't show us the code) and prints our information every time a malloc occurs, so I do know that it's possible.
Can anyone suggest a working method??
Here is the code that I used and get nothing:
mymalloc.c
#ifdef RUNTIME
// Run-time interposition of malloc and free based on // dynamic linker's (ld-linux.so) LD_PRELOAD mechanism #define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h> #include <dlfcn.h>
void *malloc(size_t size) {
static void *(*mallocp)(size_t size) = NULL; char *error;
void *ptr;
// get address of libc malloc
if (!mallocp) {
mallocp = dlsym(RTLD_NEXT, "malloc"); if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(EXIT_FAILURE);
}
}
ptr = mallocp(size);
printf("malloc(%d) = %p\n", (int)size, ptr); return ptr;
}
#endif
test.c
#include <stdio.h>
#include <stdlib.h>
int main(){
printf("main\n");
int* a = malloc(sizeof(int)*5);
a[0] = 1;
printf("end\n");
}
The result i'm getting:
$ gcc -o test test.c
$ gcc -DRUNTIME -shared -fPIC mymalloc.c -o mymalloc.so
$ LD_PRELOAD=./mymalloc.so ./test
Segmentation Fault
This is the code that I tried and got segmentation fault (from https://gist.github.com/iamben/4124829):
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void* malloc(size_t size)
{
static void* (*rmalloc)(size_t) = NULL;
void* p = NULL;
// resolve next malloc
if(!rmalloc) rmalloc = dlsym(RTLD_NEXT, "malloc");
// do actual malloc
p = rmalloc(size);
// show statistic
fprintf(stderr, "[MEM | malloc] Allocated: %lu bytes\n", size);
return p;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_LEN 128
int main(int argc, const char *argv[])
{
char *c;
char *str1 = "Hello ";
char *str2 = "World";
//allocate an empty string
c = malloc(STR_LEN * sizeof(char));
c[0] = 0x0;
//and concatenate str{1,2}
strcat(c, str1);
strcat(c, str2);
printf("New str: %s\n", c);
return 0;
}
The makefile from the git repo didn't work so I manually compiled the files and got:
$ gcc -shared -fPIC libint.c -o libint.so
$ gcc -o str str.c
$ LD_PRELOAD=./libint.so ./str
Segmentation fault
I have been doing this for hours and I still get the same incorrect result, despite the fact that I copied textbook code. I would really appreciate any help!!
One way to deal with this is to turn off the printf when your return is called recursively:
static char ACallIsInProgress = 0;
if (!ACallIsInProgress)
{
ACallIsInProgress = 1;
printf("malloc(%d) = %p\n", (int)size, ptr);
ACallIsInProgress = 0;
}
return ptr;
With this, if printf calls malloc, your routine will merely call the actual malloc (via mallocp) and return without causing another printf. You will miss printing information about a call to malloc that the printf does, but that is generally tolerable when interposing is being used to study the general program, not the C library.
If you need to support multithreading, some additional work might be needed.
The printf implementation might allocate a buffer only once, the first time it is used. In that case, you can initialize a flag that turns off the printf similar to the above, call printf once in the main routine (maybe be sure it includes a nice formatting task that causes printf to allocate a buffer, not a plain string), and then set the flag to turn on the printf call and leave it set for the rest of the program.
Another option is for your malloc routine not to use printf at all but to cache data in a buffer to be written later by some other routine or to write raw data to a file using write, with that data interpreted and formatted by a separate program later. Or the raw data could be written by a pipe to a program that formats and prints it and that is not using your interposed malloc.
I'm quite new to C and run into strange problem that I can not explain or solve.
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
void main ()
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in sock_addr;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(1500);
connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
puts("A");
char foo[9];
puts("B");
close(sock);
}
Code above prints out following lines:
A
B
If I comment out char foo[9] or change 9 to some smaller value then nothing is being printed out and program hangs. Looks like connect is that makes program to freeze but I don't see anything wrong on that line.
How to fix above code so that char foo[9] can be removed and program still prints out A and B and then exits? Why completely unrelated char foo[9] avoids program to freeze?
I'm using GCC 6.3.0 on Ubuntu.
Converting comments to an answer.
The code shown has an incorrect return type for the main() function on Linux. That is required to be int on all systems except Windows — only on Windows can you possibly hope to use void main(). See What should main() return in C and C++ for more information.
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
int main(void)
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
// missed error check - probably not critical
struct sockaddr_in sock_addr;
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = htons(1500);
// missed intialization of sock_addr.sin_addr - crucial!
// omitted trace printing before the call
connect(sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
// missed error check — possibly critical
// omitted trace printing after the call - not crucial because of puts() calls
puts("A");
char foo[9];
puts("B");
close(sock);
}
Have you tried error checking the system calls? You set the port and family but not the IP address when you try to connect — that is dubious at best, erroneous at worst. I'm not immediately sure why it causes the symptoms you're seeing, but there are problems en route to where the trouble occurs. It could be that your changed code changes the IP address part of sock_addr and your system is hanging trying to contact an uncontactable machine.
How long have you waited before deciding the program's frozen?
Have you tried adding fprintf(stderr, "BC\n"); before the call to connect() and fprintf(stderr, "AC\n"); after it? Does the call hang?
Are you using the optimizer at all?
Do you compile with warnings enabled, such as warnings for unused variables? (Use gcc -Wall -Werror -Wextra -Wstrict-prototypes -Wmissing-prototypes as a starting point — if it doesn't compile cleanly under those options, it quite possibly won't run cleanly either. Include -g for debug information and -O3; if you're doing serious debugging in a debugger, then drop the -O3.)
The code doesn't initialize the sock_addr variable properly — it doesn't set the sin_addr at all, so you're connecting to an indeterminate IP address (you've literally no idea what you're trying to connect to). At minimum, use struct sockaddr_in sock_addr = { 0 }; to set it to zeros. Or use memset(&sock_addr, '\0', sizeof(sock_addr));. You're invoking undefined behaviour because you don't initialize the structure properly. And variable responses from compilers and optimizers is symptomatic of undefined behaviour.
Karmo Rosental notes:
It is connecting to localhost when it's not freezing but your suggestion struct sockaddr_in sock_addr = { 0 }; helped to avoid freezing in GCC.
I asked a question Using sockets in multithread server yesterday. In this question I described segmentation fault under Solaris in multithreaded server. Now I have found the core of error and written code, that shortly demonstrates it:
#include <stdlib.h>
#include <pthread.h>
int main(int argc, char *argv[])
{
pthread_attr_t *attr;
attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
malloc(0);
malloc(0); //Segmentation fault there
return 0;
}
Second malloc crashes with Segmentation fault.
While this code executes normally:
#include <stdlib.h>
#include <pthread.h>
int main(int argc, char *argv[])
{
pthread_attr_t *attr;
attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
// pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
malloc(0);
malloc(0);
return 0;
}
Could you please explain the reason of the error?
P.S.: I compile with gcc -pthreads -lpthread -D_REENTRANT keys.
From the docs on pthread_attr_setdetachstate():
The behavior is undefined if the value specified by the attr argument to pthread_attr_getdetachstate() or pthread_attr_setdetachstate() does not refer to an initialized thread attributes object.
It's possible that the pthread_attr_t object the attr argument points to contains a pointer to some state maintained by the pthreads library. If it hasn't been initialized, that pointer would be garbage so the pthread_attr_setdetachstate() call might corrupt the heap.
See the pthread_attr_init() function to see how to properly initialize the attributes object.
When I use gdb to debug a program written in C, the command disassemble shows the codes and their addresses in the code memory segmentation. Is it possible to know those memory addresses at runtime? I am using Ubuntu OS. Thank you.
[edit] To be more specific, I will demonstrate it with following example.
#include <stdio.h>
int main(int argc,char *argv[]){
myfunction();
exit(0);
}
Now I would like to have the address of myfunction() in the code memory segmentation when I run my program.
Above answer is vastly overcomplicated. If the function reference is static, as it is above, the address is simply the value of the symbol name in pointer context:
void* myfunction_address = myfunction;
If you are grabbing the function dynamically out of a shared library, then the value returned from dlsym() (POSIX) or GetProcAddress() (windows) is likewise the address of the function.
Note that the above code is likely to generate a warning with some compilers, as ISO C technically forbids assignment between code and data pointers (some architectures put them in physically distinct address spaces).
And some pedants will point out that the address returned isn't really guaranteed to be the memory address of the function, it's just a unique value that can be compared for equality with other function pointers and acts, when called, to transfer control to the function whose pointer it holds. Obviously all known compilers implement this with a branch target address.
And finally, note that the "address" of a function is a little ambiguous. If the function was loaded dynamically or is an extern reference to an exported symbol, what you really get is generally a pointer to some fixup code in the "PLT" (a Unix/ELF term, though the PE/COFF mechanism on windows is similar) that then jumps to the function.
If you know the function name before program runs, simply use
void * addr = myfunction;
If the function name is given at run-time, I once wrote a function to find out the symbol address dynamically using bfd library. Here is the x86_64 code, you can get the address via find_symbol("a.out", "myfunction") in the example.
#include <bfd.h>
#include <stdio.h>
#include <stdlib.h>
#include <type.h>
#include <string.h>
long find_symbol(char *filename, char *symname)
{
bfd *ibfd;
asymbol **symtab;
long nsize, nsyms, i;
symbol_info syminfo;
char **matching;
bfd_init();
ibfd = bfd_openr(filename, NULL);
if (ibfd == NULL) {
printf("bfd_openr error\n");
}
if (!bfd_check_format_matches(ibfd, bfd_object, &matching)) {
printf("format_matches\n");
}
nsize = bfd_get_symtab_upper_bound (ibfd);
symtab = malloc(nsize);
nsyms = bfd_canonicalize_symtab(ibfd, symtab);
for (i = 0; i < nsyms; i++) {
if (strcmp(symtab[i]->name, symname) == 0) {
bfd_symbol_info(symtab[i], &syminfo);
return (long) syminfo.value;
}
}
bfd_close(ibfd);
printf("cannot find symbol\n");
}
To get a backtrace, use execinfo.h as documented in the GNU libc manual.
For example:
#include <execinfo.h>
#include <stdio.h>
#include <unistd.h>
void trace_pom()
{
const int sz = 15;
void *buf[sz];
// get at most sz entries
int n = backtrace(buf, sz);
// output them right to stderr
backtrace_symbols_fd(buf, n, fileno(stderr));
// but if you want to output the strings yourself
// you may use char ** backtrace_symbols (void *const *buffer, int size)
write(fileno(stderr), "\n", 1);
}
void TransferFunds(int n);
void DepositMoney(int n)
{
if (n <= 0)
trace_pom();
else TransferFunds(n-1);
}
void TransferFunds(int n)
{
DepositMoney(n);
}
int main()
{
DepositMoney(3);
return 0;
}
compiled
gcc a.c -o a -g -Wall -Werror -rdynamic
According to the mentioned website:
Currently, the function name and offset only be obtained on systems that use the ELF
binary format for programs and libraries. On other systems, only the hexadecimal return
address will be present. Also, you may need to pass additional flags to the linker to
make the function names available to the program. (For example, on systems using GNU
ld, you must pass (-rdynamic.)
Output
./a(trace_pom+0xc9)[0x80487fd]
./a(DepositMoney+0x11)[0x8048862]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(TransferFunds+0x11)[0x8048885]
./a(DepositMoney+0x21)[0x8048872]
./a(main+0x1d)[0x80488a4]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7e16775]
./a[0x80486a1]
About a comment in an answer (getting the address of an instruction), you can use this very ugly trick
#include <setjmp.h>
void function() {
printf("in function\n");
printf("%d\n",__LINE__);
printf("exiting function\n");
}
int main() {
jmp_buf env;
int i;
printf("in main\n");
printf("%d\n",__LINE__);
printf("calling function\n");
setjmp(env);
for (i=0; i < 18; ++i) {
printf("%p\n",env[i]);
}
function();
printf("in main again\n");
printf("%d\n",__LINE__);
}
It should be env[12] (the eip), but be careful as it looks machine dependent, so triple check my word. This is the output
in main
13
calling function
0xbfff037f
0x0
0x1f80
0x1dcb
0x4
0x8fe2f50c
0x0
0x0
0xbffff2a8
0xbffff240
0x1f
0x292
0x1e09
0x17
0x8fe0001f
0x1f
0x0
0x37
in function
4
exiting function
in main again
37
have fun!