|
List Info
Thread: Mentor for C self study wanted
|
|
| Mentor for C self study wanted |
  Germany |
2007-10-23 13:44:52 |
Hello,
I'm abaout to learn C (really learn it, not just to be able
to tinker arround
with).
So I bought a book which has some practices in each
chapter.
Now I wrote the little programs and they were almost
correct, but the things
going wrog aren't explained in that book.
Probably it has to do with the compiler, at least it was the
case in one
example.
So I wanted to ask if somebody could be so kind and answer
me occasional
questions by private mail.
The first one was for example the attached code: Why does it
segfault?
Thanks in advance,
-Harry
P.S. I will change comment language of course. I'm UTC -1
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |
  Germany |
2007-10-23 15:01:34 |
On Tue, 23 Oct 2007 20:44:52 +0200
Harald Schmalzbauer <h.schmalzbauer omnisec.de> wrote:
> The first one was for example the attached code: Why
does it segfault?
Mailman ate the attachment... Can't see it here.
-cpghost.
--
Cordula's Web. http://www.cordula.ws/
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |
  United States |
2007-10-23 15:24:54 |
In response to cpghost <cpghost cordula.ws>:
> On Tue, 23 Oct 2007 20:44:52 +0200
> Harald Schmalzbauer <h.schmalzbauer omnisec.de> wrote:
>
> > The first one was for example the attached code:
Why does it segfault?
>
> Mailman ate the attachment... Can't see it here.
I may be out of line, but I think if you're using FreeBSD as
your
learning platform, that it wouldn't be a problem to ask this
list.
Although, you'll have to include your code inline to get
past the
sanitizers.
--
Bill Moran
http://www.potentialtech
.com
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |
  Germany |
2007-10-23 16:24:09 |
Am Dienstag, 23. Oktober 2007 22:24:54 schrieb Bill Moran:
> In response to cpghost <cpghost cordula.ws>:
> > On Tue, 23 Oct 2007 20:44:52 +0200
> >
> > Harald Schmalzbauer <h.schmalzbauer omnisec.de> wrote:
> > > The first one was for example the attached
code: Why does it segfault?
> >
> > Mailman ate the attachment... Can't see it here.
>
> I may be out of line, but I think if you're using
FreeBSD as your
> learning platform, that it wouldn't be a problem to ask
this list.
>> Harald Schmalzbauer wrote:
> > Am Dienstag, 23. Oktober 2007 21:43:52 schrieben
Sie:
> >>> Hello Aryeh,
> >>>
> >>> I'm willing to pay fair fees, but are you
interested in "micro payment"
> >>> ;) ?
> >>
> >> For other reasons I love micro payments.
> >>
> >>> Serious, I'll have the one or other short
question per week (I'm
> >>> usually busy, just making spare time
lessons from my book (UTC-1 spare
> >>> time)).
> >>
> >> Just so I know what level to present on what
is your background in CS
> >> and programming?
> >
> > CS??
> > I'm able to solve problems analytically, but I
don't know any language
> > really well.
> > I know bourne shell, csh, pascal, and basic. And a
tiny bit asm, but
> > that's been on ZX81.
>
> Although, you'll have to include your code inline to
get past the
> sanitizers.
Thanks all,
here was my example, just for completeness, I found mentors
for my needs.
Thanks a lot to all!
#include <stdio.h>
void main()
{
short nnote;
// Numerischen Notenwert einlesen
printf("Bitte numerischen Schulnotenwert eingeben:
");
scanf("%d",&nnote);
switch (nnote)
{
case 1: printf("Die Note %d entspricht sehr
gut.",nnote);
break;
case 2: printf("Die Note %d entspricht
gut.",nnote);
break;
case 3: printf("Die Note %d entspricht
befriedigend.",nnote);
break;
case 4: printf("Die Note %d entspricht
ausreichend.",nnote);
break;
case 5: printf("Die Note %d entspricht
mangelhaft.",nnote);
break;
case 6: printf("Die Note %d entspricht
ungenügend.",nnote);
break;
default: printf("%d ist keine zulässige
Schulnote!");
}
printf("n");
}
P.S.:
I found that declaring nnote as int soleves my problem, but
I couldnÄt
understand why.
Another one was the result of default: nnote was -1077942208
instead of 9 for
example.
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |
  Germany |
2007-10-23 16:43:19 |
Am Dienstag, 23. Oktober 2007 23:24:09 schrieb Harald
Schmalzbauer:
[*snip*]
> > Although, you'll have to include your code inline
to get past the
> > sanitizers.
>
> Thanks all,
>
> here was my example, just for completeness, I found
mentors for my needs.
>
> Thanks a lot to all!
>
>
> #include <stdio.h>
>
> void main()
> {
> short nnote;
>
> // Numerischen Notenwert einlesen
> printf("Bitte numerischen Schulnotenwert
eingeben: ");
> scanf("%d",&nnote);
>
> switch (nnote)
> {
> case 1: printf("Die Note %d entspricht sehr
gut.",nnote);
> break;
[snip]
> default: printf("%d ist keine zulässige
Schulnote!");
> }
> printf("n");
> }
>
> P.S.:
> I found that declaring nnote as int soleves my problem,
but I couldnÄt
> understand why.
> Another one was the result of default: nnote was
-1077942208 instead of 9
> for example.
Ok, the last one is a "typo", I forgot
...ote!",%d);.
But interesting that ther's some output. Constant
output....
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |
  United States |
2007-10-23 17:18:00 |
At 04:24 PM 10/23/2007, Harald Schmalzbauer wrote:
>Am Dienstag, 23. Oktober 2007 22:24:54 schrieb Bill
Moran:
> > In response to cpghost <cpghost cordula.ws>:
> > > On Tue, 23 Oct 2007 20:44:52 +0200
> > >
> > > Harald Schmalzbauer <h.schmalzbauer omnisec.de> wrote:
> > > > The first one was for example the
attached code: Why does it segfault?
> > >
> > > Mailman ate the attachment... Can't see it
here.
> >
> > I may be out of line, but I think if you're using
FreeBSD as your
> > learning platform, that it wouldn't be a problem
to ask this list.
> >> Harald Schmalzbauer wrote:
> > > Am Dienstag, 23. Oktober 2007 21:43:52
schrieben Sie:
> > >>> Hello Aryeh,
> > >>>
> > >>> I'm willing to pay fair fees, but are
you interested in "micro payment"
> > >>> ;) ?
> > >>
> > >> For other reasons I love micro payments.
> > >>
> > >>> Serious, I'll have the one or other
short question per week (I'm
> > >>> usually busy, just making spare time
lessons from my book (UTC-1 spare
> > >>> time)).
> > >>
> > >> Just so I know what level to present on
what is your background in CS
> > >> and programming?
> > >
> > > CS??
> > > I'm able to solve problems analytically, but
I don't know any language
> > > really well.
> > > I know bourne shell, csh, pascal, and basic.
And a tiny bit asm, but
> > > that's been on ZX81.
> >
> > Although, you'll have to include your code inline
to get past the
> > sanitizers.
>
>Thanks all,
>
>here was my example, just for completeness, I found
mentors for my needs.
>
>Thanks a lot to all!
>
>
>#include <stdio.h>
>
>void main()
>{
> short nnote;
>
> // Numerischen Notenwert einlesen
> printf("Bitte numerischen Schulnotenwert
eingeben: ");
> scanf("%d",&nnote);
>
> switch (nnote)
> {
> case 1: printf("Die Note %d entspricht sehr
gut.",nnote);
> break;
> case 2: printf("Die Note %d entspricht
gut.",nnote);
> break;
> case 3: printf("Die Note %d entspricht
befriedigend.",nnote);
> break;
> case 4: printf("Die Note %d entspricht
ausreichend.",nnote);
> break;
> case 5: printf("Die Note %d entspricht
mangelhaft.",nnote);
> break;
> case 6: printf("Die Note %d entspricht
ungenügend.",nnote);
> break;
> default: printf("%d ist keine zulässige
Schulnote!");
> }
> printf("n");
>}
>
>P.S.:
>I found that declaring nnote as int soleves my problem,
but I couldnÄt
>understand why.
>Another one was the result of default: nnote was
-1077942208 instead of 9 for
>example.
if you check the man page on scanf:
d Matches an optionally signed decimal integer; the
next pointer must
be a pointer to int.
You shouldn't try to put a short into an int. Always
declare the correct
size for variables. Your segv is because scanf was trying
to put an int
where it won't fit.
You will get the same result if you go off the end of an
array.
-Derek
--
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
MailScanner thanks transtec Computers for their support.
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |
  Germany |
2007-10-23 17:26:49 |
On Tue, 23 Oct 2007 23:24:09 +0200
Harald Schmalzbauer <h.schmalzbauer omnisec.de> wrote:
> #include <stdio.h>
>
> void main()
> {
> short nnote;
^^^^^
> // Numerischen Notenwert einlesen
> printf("Bitte numerischen Schulnotenwert
eingeben: ");
> scanf("%d",&nnote);
^^^^^
> I found that declaring nnote as int soleves my problem,
but I
> couldnÄt understand why.
> Another one was the result of default: nnote was
-1077942208 instead
> of 9 for example.
There's a mismatch here: scanf("%d", ...) expects
a pointer to int,
while &nnote is a pointer to a short. Normally, an int
occupies more
bytes in memory than a short (typically sizeof(int) == 4 on
32bit
platforms, and sizeof(int) == 8 on 64bit platforms; while
typically
sizeof(short) == 2).
So scanf(3) tries to store the result into 4 bytes, but
you've provided
a pointer to only 2 bytes of memory. Where will the other 2
bytes be
stored by scanf? In your example, short nnote is an
automatic variable:
i.e. it's stored on the stack. So the other 2 bytes will be
also saved
on the stack, on a place that's not reserved for this. There
could be
anything there, like, say, a part of the return address for
the
function, or it could be on some page in memory that's
read-only or
non-allocated. In either case, the program behaviour is
undefined, and
this normally means it dumps core.
So either replace "short nnote" with "int
nnote", OR change "%d"
to the appropriate format string identifier for short int
"%hd"
(look up "man scanf" for a list of those
identifiers), both in
scanf and printf calls.
-cpghost.
--
Cordula's Web. http://www.cordula.ws/
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |
  Germany |
2007-10-23 17:52:08 |
On Tue, 23 Oct 2007 23:36:40 +0100
Bruce Cran <bruce cran.org.uk> wrote:
> cpghost wrote:
>
> > There's a mismatch here: scanf("%d",
...) expects a pointer to int,
> > while &nnote is a pointer to a short.
Normally, an int occupies more
> > bytes in memory than a short (typically
sizeof(int) == 4 on 32bit
> > platforms, and sizeof(int) == 8 on 64bit
platforms; while typically
> > sizeof(short) == 2).
>
> I think short and int stay the same on both 32 and 64
bit platforms,
> while it's only long that gets bumped to 8 bytes. At
least that
> seems to be what happens on FreeBSD amd64.
Hmmm... yep, you're right, I'm wrong! I've switched
compilers
too often recently. Yes, on gcc sizeof(int) == 4 on both
32bit and
64bit. Thanks for pointing this out: I stay corrected. ;)
--
Cordula's Web. http://www.cordula.ws/
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |

|
2007-10-23 17:58:29 |
Am Dienstag, 23. Oktober 2007 23:24:09 schrieb Harald
Schmalzbauer:
> #include <stdio.h>
>
> void main()
> {
> short nnote;
>
> // Numerischen Notenwert einlesen
> printf("Bitte numerischen Schulnotenwert
eingeben: ");
> scanf("%d",&nnote);
man 3 scanf (most important thing to look at with any such
problem is the
C-library documentation, which is excellent on FreeBSD) says
that for "%d"
the passed pointer has to be a pointer to
"integer", which &nnote is not.
&nnote is a pointer to short, which points to 2 bytes,
whereas a pointer to
integer is a pointer to 4 bytes of storage.
Generally, nnote is reserved by the compiler on the stack
(as it's a local
variable) with two bytes (but this depends on your
platform), and &nnote
points to the beginning of this area.
As you are probably running on a little-endian architecture,
the layout that
scanf presumes is (from low to high):
---> increasing addresses
lsbyte 2 3 msbyte
^
|-- &nnote points here
of which only the first two are interpreted as nnote by the
rest of the
program; the upper two are different stack content (probably
a return address
to the C initialization code calling main(), or a pushed
stack pointer, or
such, as your procedure defines no other locals, see
below).
Now, when scanf assigns the four bytes, it'll properly enter
the lower two
bytes of the integer into "lsbyte 2" (which is
nnote, in the same byte
order), but overwrite two bytes that are above it.
When main() finishes, the (now broken) saved address (of
which "3 msbyte" is
the lower half) is popped, which leads to the SIGSEGV you're
seeing.
In case you were on big-endian, the result would be
different (i.e., the order
would be reversed, so that nnote would always be zero or
minus one in case
you entered small integral values in terms of absolute
value), but
effectively, the return address would be overwritten as
well, breaking it.
This is effectively what can be called a buffer-overflow.
Just to finish this: the proper format would be
"%hd", for which the flag "h"
signifies that the pointer is a pointer to a "short
int", also documented in
man 3 scanf.
Why aren't you seeing this behaviour with printf (i.e., why
can you pass a
short but still specify "%d")? Because C defines
that functions that take a
variable number of arguments (of which printf is one such)
get each argument
as type "long" (the type that's at least as big as
a pointer on the current
platform), so when passing a short as argument to a var-args
function, the
C-compiler inserts code which makes sure that the value is
promoted to a long
in the argument stack for printf. scanf is also a varargs
function, but
you're not passing the value of nnote, but rather a pointer
to it, which
(should) already be as wide as a long.
Finally, looking at (parts of) the assembly that gcc
generates (on a
little-endian i386 machine):
.globl main
.type main, function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
; Set up the pointer to the local frame (EBP on i386). All
locals are
; relative to EBP in a function.
movl %esp, %ebp
; ECX is the first (hidden) local.
pushl %ecx
subl $20, %esp
subl $12, %esp
pushl $.LC0
call printf
addl $16, %esp
subl $8, %esp
; Load the effective address of EBP-6, i.e., nnote, into
EAX, which
; is pushed for scanf. scanf will thus write its output on
EBP-6 up to
; EBP-3, where EBP-4 and EBP-3 are part of the value that's
been
; pushed in the "pushl %ecx" above.
leal -6(%ebp), %eax
pushl %eax
pushl $.LC1
call scanf
...
; Restore the value at EBP-4 (i.e., the ECX that was pushed
above) into
; ECX at function exit. This value has been corrupted by the
integer
; assignment due to scanf.
movl -4(%ebp), %ecx
leave
; Restore the stack pointer from the (invalidated) %ecx,
i.e. produce a
; bogus stack pointer.
leal -4(%ecx), %esp
ret
This produces a segfault, after the return to the C
initialization code,
simply because the stack pointer is totally bogus.
> P.S.:
> I found that declaring nnote as int soleves my problem,
but I couldnÄt
> understand why.
Everything clear now?
--
Heiko Wundram
Product & Application Development
-------------------------------------
Office Germany - EXPO PARK HANNOVER
Beenic Networks GmbH
Mailänder Straße 2
30539 Hannover
Fon +49 511 / 590 935 - 15
Fax +49 511 / 590 935 - 29
Mobil +49 172 / 437 3 734
Mail wundram beenic.net
Beenic Networks GmbH
-------------------------------------
Sitz der Gesellschaft: Hannover
Geschäftsführer: Jorge Delgado
Registernummer: HRB 61869
Registergericht: Amtsgericht Hannover
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
| Re: Mentor for C self study wanted |
  Germany |
2007-10-23 21:28:28 |
On Tue, 23 Oct 2007 23:24:09 +0200
Harald Schmalzbauer <h.schmalzbauer omnisec.de> wrote:
> #include <stdio.h>
>
> void main()
> {
> short nnote;
>
> // Numerischen Notenwert einlesen
> printf("Bitte numerischen Schulnotenwert
eingeben: ");
> scanf("%d",&nnote);
>
> switch (nnote)
> {
> case 1: printf("Die Note %d entspricht sehr
gut.",nnote);
> break;
> case 2: printf("Die Note %d entspricht
gut.",nnote);
> break;
> case 3: printf("Die Note %d entspricht
befriedigend.",nnote);
> break;
> case 4: printf("Die Note %d entspricht
ausreichend.",nnote);
> break;
> case 5: printf("Die Note %d entspricht
mangelhaft.",nnote);
> break;
> case 6: printf("Die Note %d entspricht
ungenügend.",nnote);
> break;
> default: printf("%d ist keine zulässige
Schulnote!");
^^^^^
^^^^^
No matching int for "%d" here. It'll print
garbage. Change to:
default: printf("%hd ist keine...!", nnote);
^^^^^^^^
> }
> printf("n");
> }
>
> P.S.:
> I found that declaring nnote as int soleves my problem,
but I
> couldnÄt understand why.
> Another one was the result of default: nnote was
-1077942208 instead
> of 9 for example.
The reason for this is that the number of arguments after
printf's
format string MUST match the number of %-place holders
(unless
you're using exotic stuff like %n, of course). If printf
misses
some arguments, it will fetch them from a place that is
implementation dependant (and that almost always means:
you'll get garbage).
Sorry for overlooking your second question... ;)
-cpghost.
--
Cordula's Web. http://www.cordula.ws/
_______________________________________________
freebsd-questions freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-que
stions
To unsubscribe, send any mail to
"freebsd-questions-unsubscribe freebsd.org"
|
|
|
|