I usually use an input file when I write programs so that I save myself from the hassle of entering digits again and again.
Here is a program which I wrote for quicksort which some where is giving me segmentation fault
#include<stdio.h>
int partition (int *,int,int);
void quicksort (int *,int,int);
int main()
{
int i,j,a[15],choice;
int length;
printf("Entering numbers in array \n");
for(i=0;i<=14;i++)
scanf("%d",&a[i]);
printf("the sorted array is\n");
length=sizeof(a);
quicksort(a,0,length-1);
for(i=0;i<=14;i++)
printf (" %d ",a[i]);
}
int partition(int *num,int p,int r)
{
int x,j,i,temp;
x=num[r];
i=-1;
for(j=0;j<=r-1;j++)
{
if(num[j]<=x)
{
i=i+1;
temp=num[i];
num[i]=num[j];
num[j]=temp;
}
}
num[i+1]=num[r];
return i+1;
}
void quicksort (int *num,int p,int r)
{
int q;
if (p<r)
{
q=partition(num,p,r);
quicksort(num,p,q-1);
quicksort(num,q+1,r);
}
}
and here is my input file input.txt
43 12 90 3 49 108 65 21 9 8 0 71 66 81
when I I compile it as follows
cc quicksort.c
./a.out < input.txt
Now the output I am getting is
Entering numbers in array
the sorted array is
Segmentation fault
What I want to know is I use gdb frequently to debug such problems.
Is it possible that in gdb I take the input from the same file input.txt
my set of commands to use gdb is
cc -g quicksort.c
gdb
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file a.out
(gdb) break quicksort.c:3
(gdb) run
Now what I want to know is how do I use the input file in gdb so that I do not enter again and again the array which I want to enter?
For debugging purposes, add this line to your program and comment out the first for-loop
int a[] = {43, 12, 90, 3, 49, 108, 65, 21, 9, 8, 0, 71, 66, 81};
To get maximum debug-information, compile it using
gcc -ggdb3 qs.c
and run it in gdb as
gdb -q ./a.out
and never exit your gdb session! If you recompile it, gdb will automatically notice and reload the binary; in this way you will always have your breakpoints set and everything else you crafted.
Since others have given you a hint to where the problem is, I might reveal a common macro to get the size of an static allocated array :-)
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
As always google is your friend in such "common" use-cases.
How to load program reading stdin and taking parameters in gdb?
Input redirection in gdb (MinGW)
The reason for the seg fault maybe this line.
length=sizeof(a);
Its 60.
Your r value max should be 15. An integer is allocated 4 bytes. So your call overflows,hence the error.
Related
Need to extract a few values from an auxiliary vector. You can read more about it here. That's where I got and slightly modified code below:
#include <stdio.h>
#include <elf.h>
int main(int argc, char* argv[], char* envp[])
{
Elf64_auxv_t *auxv;
while (*envp++ != NULL); /* from stack diagram above: *envp = NULL marks end of envp */
for (auxv = (Elf64_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++)
/* auxv->a_type = AT_NULL marks the end of auxv */
{
if (AT_EXECFN == auxv->a_type)
{
char *str = (char *)auxv->a_un.a_val;
printf("%s\n", str);
break;
}
}
return 0;
}
I compile the code with gcc -g aux-extractor.c.
Here is the weird part. If I run the code as ./a.out I get and output as ./a.out which makes sense. However when I debug it in gdb and print the value at a specific address I get /tmp/a.out, which also makes sense I compiled my code in /tmp directory. My question is why I'm getting two different results, a.out and /tmp/a.out?
Here is my debugging session (pay attention to the output of the x/s command:
$ gdb ./a.out
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu". T
ype "show configuration" for configuration details.
For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...
(gdb) start
Temporary breakpoint 1 at 0x1149: file auxv-extractor.c, line 5.
Starting program: /tmp/a.out
Temporary breakpoint 1, main (argc=21845, argv=0x0, envp=0x5555555551c0 <__libc_csu_init>) at auxv-extractor.c:5
5 {
(gdb) break 15
Breakpoint 2 at 0x555555555198: file auxv-extractor.c, line 15.
(gdb) c
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffe408, envp=0x7fffffffe520) at auxv-extractor.c:15
15 printf("%s\n", str);
(gdb) x/s str
0x7fffffffefed: "/tmp/a.out"
(gdb)
When gdb runs your program, it does so by executing /tmp/a.out, having expanded the path from the ./a.out on the command line.
GDB has a habit of starting the program with $(realpath ./a.out) when ./a.out is given on the command line.
I've tried to set exec-wrapper as a way to avoid this, but was not successful -- even when setting exec-wrapper wrapper.sh with this contents:
#!/bin/bash
exec -a "./a.out" "$#"
the AT_EXECFN remains /tmp/a.out.
This answer shows how to pause the program after main() to make it easy to attach GDB from "outside". AT_EXECFN will be set to ./a.out as expected, and you can continue debugging as you normally would.
Please tell me why my program isn't working. I think it may be a segmentation fault but I can't identify it. If possible please correct it.
I'm trying to convert from array of char to an array of int using function chartoint() and when I remove it from main it works so the problem is in the function.
#include<stdio.h>
#include<stdlib.h>
void chartoint(char c[],int * x){
int i;
while(c[i]!='.'||c[i]!='\0'){
if((int)c[i]>57){ *(x+i) = (int)c[i] - 54;}
else{ *(x+i) = (c[i]-'0'); }
i++;
}
*(x+i) = -1; i++;
while(c[i]!='\0'){
if((int)c[i]>57){ *(x+i) = (int)c[i] - 54;}
else{ *(x+i) = (c[i]-'0'); }
i++;
}
}
int main(){
int n;
printf(" number of characters ");
scanf("%d",&n);
char c[n+1];
for(int i=0; i<n; i++){
scanf("%c",&c[i]);
}
c[n]='\0';
int * x = (int*)malloc(n*sizeof(int));
chartoint(c,x);
for(int i=0; i<n; i++){
printf("%d",*(x+i));
}
free(x);
return 0;
}
You need to learn how to use a debugger.
Here's the output when you use a debugger to run your C program (gdb, in this case). I named your compiled program t:
$ gdb ./t
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.3) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./t...done.
(gdb) r
Starting program: /home/youruser/t
number of characters 3
a
Program received signal SIGSEGV, Segmentation fault.
0x00000000004006ba in chartoint (c=0x7fffffffe540 "\na\n", x=0x602010) at t.c:6
6 while(c[i]!='.'||c[i]!='\0'){
(gdb) bt
#0 0x00000000004006ba in chartoint (c=0x7fffffffe540 "\na\n", x=0x602010) at t.c:6
#1 0x0000000000400884 in main () at t.c:29
(gdb)
It's basically saying that you are getting a segmentation fault (SIGSEGV) when running line 6. The reason is probably that i it's being used without being initialized first.
If you are using an IDE to do this (Visual Studio, Visual Studio Code) you will probably have and embedded debugger.
System
Fresh install of codeblocks 12.11 + mingw pack.
win7 64
gcc 4.7.1
gdb 7.5
Example code
Compiled with -g and no optimization.
#include <stdio.h>
void foo(int a, int b);
int main() {
foo(400, 42);
return 0;
}
void foo(int a, int b) {
a = a - 10;
b = a + 1;
printf("y2 %d\n", b);
}
Problem
I put a breakpoint on "void foo(int a, int b)" and I look value of b as I step through the 3 lines.
Either with the codeblocks debugging features or with the gdb command line, the value of b is 42 instead of being 391.
The console output is correct, 391.
GDB commands
C:\DebugTest>"C:\Program Files (x86)\CodeBlocks\MinGW\bin\gdb.exe"
GNU gdb (GDB) 7.5
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file bin/Debug/DebugTest.exe
Reading symbols from C:\DebugTest\bin\Debug\DebugTest.exe...done.
(gdb) break foo
Breakpoint 1 at 0x401363: file C:\DebugTest\main.c, line 14.
(gdb) run
Starting program: C:\DebugTest\bin\Debug\DebugTest.exe
[New Thread 3596.0x658]
Breakpoint 1, foo (a=400, b=42) at C:\DebugTest\main.c:14
14 a = a - 10;
(gdb) print b
$1 = 42
(gdb) step
15 b = a + 1;
(gdb) print b
$2 = 42
(gdb) step
17 printf("y2 %d\n", b);
(gdb) print b
$3 = 42
(gdb)
Remarks
When the same operations are done without a function, with a and b as local variables inside main, the debug output is correct.
When compiled with gcc 4.4.1, the debug output is correct.
Any idea what could be wrong ? =)
I searched on gcc bugzilla and found this bug report :
Bug 54218 - Debug info for function parameters is incorrect when compiled with -O0"
Althoug the report is about gcc 4.8 and I'm using 4.7, I tried the proposed workaround and it works !
Compiling with -fvar-tracking allows GDB to print the correct value for b after assignment.
gcc does not generate debugging info correctly for values that are in registers -- either values that have been put in registers or values that start there due to the calling conventions. This is a long-standing problem with gcc since at least 4.0, and makes it tricky to debug things.
Sometimes the optimizer is smarter than the debugger. Try debugging unoptimized code, or step through disassembly and watch the HW registers directly rather than stepping through C source lines and watching the debugger's idea of what the variables are.
I'm currently following this video on how to work with assembly and gdb, using this C program, but I'm running into a problem. Here's what I do to compile and run gdb:
chiggins#host:~/assem$ gcc -ggdb -o SimpleDemo SimpleDemo.c
chiggins#host:~/assem$ gdb ./SimpleDemo
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/chiggins/assem/SimpleDemo...done.
(gdb) list
4 int add(int x, int y)
5 {
6 int z =10;
7
8 z = x + y;
9 return z;
10 }
11
12 main(int argc, char **argv)
13 {
(gdb)
14 int a = atoi(argv[1]);
15 int b = atoi(argv[2]);
16 int c;
17 char buffer[100];
18
19 gets(buffer);
20 puts(buffer);
21
22 c = add(a,b);
23
(gdb)
24 printf("Sum of %d+%d = %d\n",a, b, c);
25
26 exit(0);
27
28 }
(gdb) run 10 20
Starting program: /home/chiggins/assem/SimpleDemo 10 20
demo
Now from where I have "demo" typed at the end, that's where the program is supposed to be accepting user input. But when I press return after typing enter, nothing happens. I can't ctrl+c out of the program, can't do anything. I end up having to kill the process from another session just so I can get control back. Any ideas why gdb is doing this, or what I might be doing wrong?
Thanks!
I'm not sure why that doesn't work for you; it works as expected here...
Still, I find it easier to run programs performing interactive I/O in a separate terminal, and perhaps it will help you.
In one terminal,
$ gdbserver --multi localhost:4242
listening on port 4242
and in another,
$ gdb ./SimpleDemo
(gdb) target extended-remote localhost:4242
Remote debugging using localhost:4242
(gdb) run 10 20
Back to the terminal running gdbserver,
Remote debugging from host 127.0.0.1
Process ./SimpleDemo created; pid=PID
demo
demo
Sum of 10+20 = 30
Child exited with status 0
Are you trying to have user input during the program? If you simply want to set command line arguments at the beginning you can just say set args ... where you can give the arguments as you would during the course of the program.
Have you tried this?
gdb --args ./SimpleDemo 10 20
Use Ctrl+Enter instead of the Enter key.
I have a multithreaded (pthreads) program in which main() calls a function omp_file_open_all() and passes in a string as char* alongwith other arguments. I was debugging something using gdb and saw that gdb does not print out the string value correctly, whereas a printf inside the function prints it out correcly.
Breakpoint 1, omp_file_open_all (fd=0x423bb950, filename=0x7f605df078e0 "", mode=-16843009) at pthread_coll_file_open.c:29
29 if(omp_get_thread_num() == MASTER)
(gdb) print filename
$1 = 0x7f605df078e0 ""
So gdb shows filename as empty, whereas a printf inside the function outputs the correct value as "/tmp/test.out". The function being called (omp_file_open_all) is defined as follows (not in the same file as main()):
int omp_file_open_all (int fd, char* filename, int mode);
I cant post my program here as this is a part of a larger code thats approx. 1500 lines of code. 'filename' is a global variable and is set in main() by the main thread before newer threads are spawned.
So this is not an error, and I merely stumbled across it, but I am interested in finding out why gdb does not display the correct value.
OS: 64bit OpenSUSE,
gdb 6.8
Thanks for your help.
There might be some thing going wrong in your code. With the following code snippet, I am getting the string printed by gdb correctly.
#include <stdio.h>
#include <stdlib.h>
void checkString( char* fileName )
{
printf("%s", fileName);
}
int main()
{
char* name = "temp";
checkString(name);
return 0;
}
mahesh-babu-vattiguntas-macbook-pro:Desktop mahesh$ gdb gdb.out
GNU gdb 6.3.50-20050815 (Apple version gdb-1469) (Wed May 5 04:36:56 UTC 2010)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done
(gdb) b gdb.c:6
Breakpoint 1 at 0x100000ebc: file gdb.c, line 6.
(gdb) run gdb.out
Starting program: /Users/mahesh/Desktop/gdb.out gdb.out
Reading symbols for shared libraries +. done
Breakpoint 1, checkString (fileName=0x100000f05 "temp") at gdb.c:6
6 printf("%s", fileName);
(gdb) p fileName
$1 = 0x100000f05 "temp"
(gdb)
Try stepping forward one line (gdb "s" command) after you hit the breakpoint, then try printing it again. I've sometimes seen gdb have trouble displaying parameter values correctly when breaking at the beginning of a function.
My first guess was that there is a scoping issue, since the name of the function parameter and your global variable is identical. However, this does not seem to be the case for the following very small program:
#include <cstdio>
static char const* filename = "something";
int foobar(char const* filename)
{
printf("%s\n", filename);
}
int main(int argc, char** argv)
{
return foobar("somethingelse");
}
Compiled with:
g++ -ggdb -g3 -O0 test.cpp -o test
GDB (7.2, also on x64 but Ubuntu) gives:
Breakpoint 1, foobar (filename=0x400706 "somethingelse") at test.cpp:7
7 printf("%s\n", filename);
(gdb) p filename
$1 = 0x400706 "somethingelse"
So it's not about scoping per-se. Also, the output suggests that the parameter is indeed an empty string at execution time. Could you please provide us with the output of bt at the same time you break into the debugger? Last two stack frames are sufficient.