I'm running Eclipse v4.6 (Neon1) RC1 on a Windows & nbsp;10 machine, and it seems to be adding single quotes around each command line argument/parameter that I pass during debug. I see this show up in memory for each argv.
Strangely I can't produce these quotes to the console with a printf (during RUN); the program successfully loads the file specified by the parameters and outputs to console.
The command line arguments are set in the application run config->Parameters tab, as (single line, no quotes added):
keyFile.txt inputFile.txt outputFile.txt
I do not see this behavior in NetBeans (in fact have switched temporarily).
The issue is this appears to be causing problems with fopen when debugging: it can't find the file. I assume both are using the same working directory, because if I use a static filename of "keyFile.txt", debug works OK.
Unfortunately my console output doesn't work in debug, so I'm a little limited at the moment.
The example code is a much trimmed down version, to demonstrate:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
// Arguments: keyfile.txt inputfile.txt outputfile.txt
char * firstArg = argv[1];
char * secArg = argv[2]; // Leaving these to show quotes on other inputs as well
char * thirdArg = argv[3];
printf("First arg:\t%s\n", firstArg);
printf("Ptr Address, uint cast:\t0x%x\n", (unsigned int) firstArg);
printf("Ptr Address, void* cast:\t%p\n", (void *) firstArg);
printf("Char at Ptr:\t%c\n\n", (char) *(firstArg));
printf("Second arg: \t%s\n", secArg);
printf("Third arg: \t%s\n", thirdArg);
FILE *fptr;
fptr = fopen(firstArg, "rb");
if (fptr == NULL)
{
perror("Error");
return -1;
}
int kLength=0;
int inputChar;
unsigned char keyin[256];
printf("\nData from file:\n");
while ((inputChar = fgetc(fptr))!=EOF) // Read KEYFILE
{
if ((kLength%8)==0) { printf("\n"); }
keyin[kLength++] = (unsigned char) inputChar;
printf("0x%x\t",inputChar);
}
return 0;
}
On Run, output is as expected/follows:
First arg: keyFile.txt
Ptr Address, uint cast: 0x6b1748
Ptr Address, void* cast: 006B1748
Char at Ptr: k
Second arg: inputFile.txt
Third arg: outputfile.txt
current Path: C:\Users\***\Google Drive\***\eclipse workspace\argTest
Data from file:
0x59 0x45 0xba 0x1e...
...
(data I expect is displayed from file ...)
But during debug, I get trapped by a null fptr, and I see the quotes in memory:
Debug memory: firstArg points to 0x6E1760:
Looking at the gdb traces, I see the single quotes here as well. Shown below is everything leading up to this point:
311,234 2-gdb-version
311,239 ~"GNU gdb (GDB) 7.6.1\n"
311,240 ~"Copyright (C) 2013 Free Software Foundation, Inc.\n"
311,240 ~"License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\nThis is fre\
e software: you are free to change and redistribute it.\nThere is NO WARRANTY, to the extent permitt\
ed by law. Type \"show copying\"\nand \"show warranty\" for details.\n"
311,240 ~"This GDB was configured as \"mingw32\".\nFor bug reporting instructions, please see:\n"
311,240 ~"<http://www.gnu.org/software/gdb/bugs/>.\n"
311,240 2^done
311,241 (gdb)
311,243 3-environment-cd "C:/Users/***/Google Drive/***/workspace/argTest"\
311,250 3^done
311,250 (gdb)
311,251 4-gdb-set breakpoint pending on
311,260 4^done
311,260 (gdb)
311,261 5-gdb-set detach-on-fork on
311,270 5^done
311,270 (gdb)
311,271 6-enable-pretty-printing
311,280 6^done
311,280 (gdb)
311,281 7-gdb-set python print-stack none
311,290 7^done
311,290 (gdb)
311,291 8-gdb-set print object on
311,300 8^done
311,300 (gdb)
311,301 9-gdb-set print sevenbit-strings on
311,310 9^done
311,310 (gdb)
311,311 10-gdb-set host-charset UTF-8
311,320 10^done
311,320 (gdb)
311,321 11-gdb-set target-charset WINDOWS-1252
311,330 11^done
311,330 (gdb)
311,331 12-gdb-set target-wide-charset UTF-16
311,340 12^done
311,340 (gdb)
311,342 13source .gdbinit
311,350 &"source .gdbinit\n"
311,350 &".gdbinit: No such file or directory.\n"
311,350 13^error,msg=".gdbinit: No such file or directory."
311,350 (gdb)
311,351 14-gdb-set target-async off
311,360 14^done
311,360 (gdb)
311,361 15-gdb-set auto-solib-add on
311,370 15^done
311,370 (gdb)
311,379 16-file-exec-and-symbols --thread-group i1 Debug/argTest.exe
311,384 16^done
311,384 (gdb)
311,385 17-gdb-set --thread-group i1 args 'keyFile.txt' 'inputFile.txt' 'outputFile.txt'
311,394 17^done
311,394 (gdb)
...
This is a known bug in Eclipse, tracked here:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=494246
My workaround is to set the arguments in .gdbinit file instead of setting in Arguments tab (in Debug Configurations), just put the line like:
set args arg1 arg2
And then, it works fine!
Related
Below is the code which i had used to understand actions command in gdb.
#include <stdio.h>
int Use_Action(int CatchedInt, char * CatchedStr)
{
printf("CatchedInt = %d, CatchedStr = %s\n", CatchedInt, CatchedStr);
return 0;
}
int main(void)
{
int PassingInt = 20;
char PassingStr[10] = "Hello";
Use_Action(PassingInt, PassingStr);
}
In GDB Tool I have done the following things with the help of https://sourceware.org/gdb/current/onlinedocs/gdb/Tracepoint-Actions.html
(gdb) trace Use_Action
Tracepoint 1 at 0x1169: file action.c, line 5.
(gdb) info tracepoints
Num Type Disp Enb Address What
1 tracepoint keep y 0x0000000000001169 in Use_Action at action.c:5
not installed on target
(gdb) actions
Enter actions for tracepoint 1, one per line.
End with a line saying just "end".
>collect CatchedInt
>end
(gdb) info tracepoints
Num Type Disp Enb Address What
1 tracepoint keep y 0x0000000000001169 in Use_Action at action.c:5
collect CatchedInt
not installed on target
If i had collect the value of "Catchedint" by command collect Catchedint, then how to display the value. Is there something I missed? or i understand this actions command in wrong way!!?
Is there something I missed?
Yes: you need to actually run the program while collecting the trace, using tstart, run and tstop commands.
If you tried that, you would likely get this error:
(gdb) tstart
You can't do that when your target is `exec'
That's because only some targets support tracepoints, and local execution doesn't. You'll need to use gdbserver instead.
i need the address of a particular array, i obtained other array's addresses with success but in this one i got stuck.. here is the main code:
int main(int argc, char** argv) {
string[0] = 0;
char polpetta[]="secret-file";
char buf[50] ;
printf("me Can I read the secret file?! \n\n");
if (argc > 2) {
vuln(argv[1]);
strcpy(buf, argv[2]) ;
} else {
printf("You forgot to read me!!!\n");
}
return 0;
}
ok i put the breakpoint after the first printf:
(gdb) b* 0x080485f3
Breakpoint 1 at 0x80485f3
(gdb) r 12 12
Starting program: /home/andrew/Desktop/Software-Security-Lab/rop/rop-vuln
me Can I read the secret file?!
Breakpoint 1, 0x080485f3 in main ()
(gdb) p &buf
$1 = (char **) 0xb7fb9ef0 <buf>
(gdb) p &polpetta
No symbol "polpetta" in current context.
ok i obtained with success the address of buf... but not the address of polpetta! so i tried with different methods:
(gdb) p $polpetta
$2 = void
(gdb) p &$polpetta
Attempt to take address of value not located in memory.
(gdb) p polpetta
No symbol "polpetta" in current context.
(gdb) info locals
No symbol table info available.
(gdb) p *polpetta
No symbol "polpetta" in current context.
what the hell?? i also tried to repeat this routine at different breakpoints inside the main function...
thanks for your kindness!
I'm trying to migrate a small c program from hpux to linux. The project compiles fine but crashes at runtime showing me a segmentation fault. I've already tried to see behind the mirror using strace and gdb but still don't understand. The relevant (truncated) parts:
tts_send_2.c
Contains a method
int sequenznummernabgleich(int sockfd, char *snd_id, char *rec_id, int timeout_quit) {
TS_TEL_TAB tel_tab_S01;
int n;
# truncated
}
which is called from within that file like this:
. . .
. . .
switch(sequenznummernabgleich(sockfd,c_snd_id,c_rec_id,c_timeout_quit)) {
/* kritischer Fehler */
case -1:
. . .
. . .
when calling that method I'm presented a segmentation fault (gdb output):
Program received signal SIGSEGV, Segmentation fault.
0x0000000000403226 in sequenznummernabgleich (sockfd=<error reading variable: Cannot access memory at address 0x7fffff62f94c>,
snd_id=<error reading variable: Cannot access memory at address 0x7fffff62f940>, rec_id=<error reading variable: Cannot access memory at address 0x7fffff62f938>,
timeout_quit=<error reading variable: Cannot access memory at address 0x7fffff62f934>) at tts_snd_2.c:498
498 int sequenznummernabgleich(int sockfd, char *snd_id, char *rec_id, int timeout_quit) {
which I just don't understand. When I'm stepping to the line where the method is called using gdb, all the variables are looking fine:
1008 switch(sequenznummernabgleich(sockfd,c_snd_id,c_rec_id,c_timeout_quit)) {
(gdb) p sockfd
$9 = 8
(gdb) p &sockfd
$10 = (int *) 0x611024 <sockfd>
(gdb) p c_snd_id
$11 = "KR", '\000' <repeats 253 times>
(gdb) p &c_snd_id
$12 = (char (*)[256]) 0xfde220 <c_snd_id>
(gdb) p c_rec_id
$13 = "CO", '\000' <repeats 253 times>
(gdb) p &c_rec_id
$14 = (char (*)[256]) 0xfde560 <c_rec_id>
(gdb) p c_timeout_quit
$15 = 20
(gdb) p &c_timeout_quit
$16 = (int *) 0xfde660 <c_timeout_quit>
I've also created an strace output. Here's the last part concerning the code shown above:
strace output
Any ideas ? I've searched the web and of course stackoverflow for hours without finding a really similar case.
Thanks
Kriz
I haven't used an HP/UX in eons but do hazily remember enough for the following suggestions:
Make sure you're initializing variables / struts correctly. Use calloc instead of malloc.
Also don't assume a specific bit pattern order: eg low byte then high byte. Ska endian-ness of the machine. There are usually macros in the compiler that will handle the appropriate ordering for you.
Update 15.10.16
After debugging for even more hours I found the real Problem. On the first line of the Method "sequenznummernabgleich" is a declaration of a struct
TS_TEL_TAB tel_tab_S01;
This is defined as following:
typedef struct {
TS_BOF_REC bof;
TS_REM_REC rem;
TS_EOF_REC eof;
int bof_len;
int rem_len;
int eof_len;
int cnt;
char teltyp[LEN_TELTYP+1];
TS_TEL_ENTRY entries[MAX_TEL];
} TS_TEL_TAB;
and it's embedded struct TS_TEL_ENTRY
typedef struct {
int len;
char tel[MAX_TEL_LEN];
} TS_TEL_ENTRY;
The problem is that the value for MAX_TEL_LEN had been changed from 512 to 1024 and thus the struct almost doubled in size what lead to that the STACK SIZE was not big enough anymore.
SOLUTION
Simply set the stack size from 8Mb to 64Mb. This can be achieved using ulimit command (under linux).
List current stack size: ulimit -s
Set stack size to 64Mb: ulimit -s 65535
Note: Values for stack size are in kB.
For a good short ref on ulimit command have a look # ss64
I have an issue with my pointer to a structure variable. I just started using GDB to debug the issue. The application stops when it hits on the line of code below due to segmentation fault. ptr_var is a pointer to a structure
ptr_var->page = 0;
I discovered that ptr_var is set to an invalid memory 0x0 after a series of function calls which caused the segmentation fault when assigning the value "0" to struct member "page". The series of function calls does not have a reference to ptr_var. The old address that used to be assigned to ptr_var is still in memory. I can still still print the values of members from the struct ptr_var using the old address. GDB session below shows that I am printing a string member of the struct ptr_var using its address
(gdb) x /s *0x7e11c0
0x7e0810: "Sample String"
I couldn't tell when the variable ptr_var gets assigned an invalid address 0x0. I'm a newbie to GDB and an average C programmer. Your assistance in this matter is greatly appreciated. Thank you.
What you want to do is set a watchpoint, GDB will then stop execution every time a member of a struct is modified.
With the following example code
typedef struct {
int val;
} Foo;
int main(void) {
Foo foo;
foo.val = 5;
foo.val = 10;
}
Drop a breakpoint at the creation of the struct and execute watch -l foo.val Then every time that member is changed you will get a break. The following is my GDB session, with my input
(gdb) break test.c:8
Breakpoint 3 at 0x4006f9: file test.c, line 8.
(gdb) run
Starting program: /usr/home/sean/a.out
Breakpoint 3, main () at test.c:9
9 foo.val = 5;
(gdb) watch -l foo.val
Hardware watchpoint 4: -location foo.val
(gdb) cont
Continuing.
Hardware watchpoint 4: -location foo.val
Old value = 0
New value = 5
main () at test.c:10
(gdb) cont
Continuing.
Hardware watchpoint 4: -location foo.val
Old value = 5
New value = 10
main () at test.c:11
(gdb) cont
If you can rerun, then break at a point where ptr_var is correct you can set a watch point on ptr_var like this: (gdb) watch ptr_var. Now when you continue every time ptr_var is modified gdb should stop.
Here's an example. This does contain undefined behaviour, as I'm trying to reproduce a bug, but hopefully it should be good enough to show you what I'm suggesting:
#include <stdio.h>
#include <stdint.h>
int target1;
int target2;
void
bad_func (int **bar)
{
/* Set contents of bar. */
uintptr_t ptr = (uintptr_t) bar;
printf ("Should clear %p\n", (void *) ptr);
ptr += sizeof (int *);
printf ("Will clear %p\n", (void *) ptr);
/* Bad! We just corrupted foo (maybe). */
*((int **) ptr) = NULL;
}
int
main ()
{
int *foo = &target1;
int *bar = &target2;
printf ("&foo = %p\n", (void *) &foo);
printf ("&boo = %p\n", (void *) &bar);
bad_func (&bar);
return *foo;
}
And here's a gdb session:
(gdb) break bad_func
Breakpoint 1 at 0x400542: file watch.c, line 11.
(gdb) r
&foo = 0x7fffffffdb88
&boo = 0x7fffffffdb80
Breakpoint 1, bad_func (bar=0x7fffffffdb80) at watch.c:11
11 uintptr_t ptr = (uintptr_t) bar;
(gdb) up
#1 0x00000000004005d9 in main () at watch.c:27
27 bad_func (&bar);
(gdb) watch foo
Hardware watchpoint 2: foo
(gdb) c
Continuing.
Should clear 0x7fffffffdb80
Will clear 0x7fffffffdb88
Hardware watchpoint 2: foo
Old value = (int *) 0x60103c <target1>
New value = (int *) 0x0
bad_func (bar=0x7fffffffdb80) at watch.c:18
18 }
(gdb)
For some reason the watchpoint appears to trigger on the line after the change was made, even though I compiled this with -O0, which is a bit of a shame. Still, it's usually close enough to help identify the problem.
For such kind of problems I often use the old electric fence library, it can be used to find bug in "software that overruns the boundaries of a malloc() memory allocation". You will find all the instructions and basic usage at this page:
http://elinux.org/Electric_Fence
(At the very end of the page linked above you will find the download link)
Code snippets from two C source files:
A.c
Channel *testChannelGet()
{
Channel *ch = channelGet (parser,parserCh);
return ch;
}
B.c
Channel *channelGet(UINT8 parser, UINT16 parserCh)
{
chnl.player = &solPlayer;
return((Channel *)&chnl);
}
I compile both files and create a static and a shared library. Now I call testChannelGet from a sample program. When I link it against the static library, it works perfectly. But if I link it against the shared library, its SEGFAULTing. Debugging tells me that the pointer returned from channelGet is changing the moment it returns. GDB output below.
174 Channel *ch = channelGet (parser,parserCh);
(gdb) s
channelGet (parser=1 '\001', parserCh=1) at B.c:15174
15174 chnl.player = &solPlayer;
(gdb) n
15175 return((Channel *)&chnl);
(gdb) p ((Channel *)&chnl)
$1 = (Channel *) 0x7ffff7fed1a0
(gdb) n
15176 }
(gdb) n
testChannelGet at A.c:175
175 return ch;
(gdb) p ch
$2 = (Channel *) 0xfffffffff7fed1a0
It seems the address value points to a different offset now - 0xfffffffff7fed1a0 vs 0x7ffff7fed1a0 . The last bytes in both addresses are the same.
Any hints? I have tried the -fPIC option to no avail.
Is there a prototype in scope for channelGet() in A.c?
If not, the results you're seeing could be explained as follows:
channelGet() is assumed to return int (due to lack of prototype), so the result is truncated to 0xf7fed1a0
then it is cast to a 64-bit pointer, so gets sign-extended to 0xfffffffff7fed1a0
(You should get complaints about this if you compile with warnings enabled, of course...)
Run your program under valgrind. Find and fix any errors it reports.