Segmentation fault in C, veroorzaakt door asprintf

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Roel911
  • Registratie: Januari 2008
  • Laatst online: 18-08 19:29
Ik probeer een C programma te debuggen, wat compiled, echter ik krijg een segmentation fault zodra het programma uitgevoerd wordt. Als ik de asprint regel uitzet door er commentaar van te maken geeft het programma geen fout bij uitvoerne. Op internet gezocht hoe dit opgelost kan worden, geen oplossing gevonden. Wel een hint naar Valgrind. Ik compile onder linux met: gcc segfault.c -g

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#include <curl/curl.h>


int main(void)
{
  char aa=0;char ab=0;
  const char validurlchar[38]= "abcdefghijklmnopqrstuvwxyz0123456789-_";
  char* source;
  asprintf(&source,"%s%s%.nl",validurlchar[aa],validurlchar[ab]);
  free(source);
}

valgrind --leak-check=full -v ./a.out
geeft:
==2646== Memcheck, a memory error detector
==2646== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==2646== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==2646== Command: ./a.out
==2646==
--2646-- Valgrind options:
--2646-- --leak-check=full
--2646-- -v
--2646-- Contents of /proc/version:
--2646-- Linux version 3.16.7-21-desktop (geeko@buildhost) (gcc version 4.8.3 20140627 [gcc-4_8-branch revision 212064] (SUSE Linux) ) #1 SMP PREEMPT Tue Apr 14 07:11:37 UTC 2015 (93c1539)
--2646-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-avx-bmi
--2646-- Page sizes: currently 4096, max supported 4096
--2646-- Valgrind library directory: /usr/lib64/valgrind
--2646-- Reading syms from /home/roel/a.out
--2646-- Reading syms from /lib64/ld-2.19.so
--2646-- Reading syms from /usr/lib64/valgrind/memcheck-amd64-linux
--2646-- object doesn't have a symbol table
--2646-- object doesn't have a dynamic symbol table
--2646-- Scheduler: using generic scheduler lock implementation.
--2646-- Reading suppressions file: /usr/lib64/valgrind/default.supp
==2646== embedded gdbserver: reading from /tmp/vgdb-pipe-from-vgdb-to-2646-by-roel-on-WHYN-001
==2646== embedded gdbserver: writing to /tmp/vgdb-pipe-to-vgdb-from-2646-by-roel-on-WHYN-001
==2646== embedded gdbserver: shared mem /tmp/vgdb-pipe-shared-mem-vgdb-2646-by-roel-on-WHYN-001
==2646==
==2646== TO CONTROL THIS PROCESS USING vgdb (which you probably
==2646== don't want to do, unless you know exactly what you're doing,
==2646== or are doing some strange experiment):
==2646== /usr/lib64/valgrind/../../bin/vgdb --pid=2646 ...command...
==2646==
==2646== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==2646== /path/to/gdb ./a.out
==2646== and then give GDB the following command
==2646== target remote | /usr/lib64/valgrind/../../bin/vgdb --pid=2646
==2646== --pid is optional if only one valgrind process is running
==2646==
--2646-- REDIR: 0x4017810 (ld-linux-x86-64.so.2:strlen) redirected to 0x3806bd01 (???)
--2646-- Reading syms from /usr/lib64/valgrind/vgpreload_core-amd64-linux.so
--2646-- object doesn't have a symbol table
--2646-- Reading syms from /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so
--2646-- object doesn't have a symbol table
==2646== WARNING: new redirection conflicts with existing -- ignoring it
--2646-- old: 0x04017810 (strlen ) R-> (0000.0) 0x3806bd01 ???
--2646-- new: 0x04017810 (strlen ) R-> (2007.0) 0x04c2c730 strlen
--2646-- REDIR: 0x40175c0 (ld-linux-x86-64.so.2:index) redirected to 0x4c2c2e0 (index)
--2646-- REDIR: 0x40177e0 (ld-linux-x86-64.so.2:strcmp) redirected to 0x4c2d880 (strcmp)
--2646-- REDIR: 0x4018510 (ld-linux-x86-64.so.2:mempcpy) redirected to 0x4c30330 (mempcpy)
--2646-- Reading syms from /lib64/libc-2.19.so
--2646-- REDIR: 0x4eba530 (libc.so.6:strcasecmp) redirected to 0x4a23770 (_vgnU_ifunc_wrapper)
--2646-- REDIR: 0x4ebc820 (libc.so.6:strncasecmp) redirected to 0x4a23770 (_vgnU_ifunc_wrapper)
--2646-- REDIR: 0x4eb9cb0 (libc.so.6:memcpy@GLIBC_2.2.5) redirected to 0x4a23770 (_vgnU_ifunc_wrapper)
--2646-- REDIR: 0x4eb8030 (libc.so.6:rindex) redirected to 0x4c2bfc0 (rindex)
--2646-- REDIR: 0x4eb06e0 (libc.so.6:malloc) redirected to 0x4c290a0 (malloc)
--2646-- REDIR: 0x4ec0ec0 (libc.so.6:strchrnul) redirected to 0x4c2ff40 (strchrnul)
==2646== Invalid read of size 1
==2646== at 0x4E7CF80: vfprintf (in /lib64/libc-2.19.so)
==2646== by 0x4EA67C2: vasprintf (in /lib64/libc-2.19.so)
==2646== by 0x4E85806: asprintf (in /lib64/libc-2.19.so)
==2646== by 0x400623: main (in /home/roel/a.out)
==2646== Address 0x61 is not stack'd, malloc'd or (recently) free'd
==2646==
==2646==
==2646== Process terminating with default action of signal 11 (SIGSEGV)
==2646== Access not within mapped region at address 0x61
==2646== at 0x4E7CF80: vfprintf (in /lib64/libc-2.19.so)
==2646== by 0x4EA67C2: vasprintf (in /lib64/libc-2.19.so)
==2646== by 0x4E85806: asprintf (in /lib64/libc-2.19.so)
==2646== by 0x400623: main (in /home/roel/a.out)
==2646== If you believe this happened as a result of a stack
==2646== overflow in your program's main thread (unlikely but
==2646== possible), you can try to increase the size of the
==2646== main thread stack using the --main-stacksize= flag.
==2646== The main thread stack size used in this run was 8388608.
--2646-- REDIR: 0x4eb0d20 (libc.so.6:free) redirected to 0x4c2a310 (free)
==2646==
==2646== HEAP SUMMARY:
==2646== in use at exit: 100 bytes in 1 blocks
==2646== total heap usage: 1 allocs, 0 frees, 100 bytes allocated
==2646==
==2646== Searching for pointers to 1 not-freed blocks
==2646== Checked 66,720 bytes
==2646==
==2646== LEAK SUMMARY:
==2646== definitely lost: 0 bytes in 0 blocks
==2646== indirectly lost: 0 bytes in 0 blocks
==2646== possibly lost: 0 bytes in 0 blocks
==2646== still reachable: 100 bytes in 1 blocks
==2646== suppressed: 0 bytes in 0 blocks
==2646== Reachable blocks (those to which a pointer was found) are not shown.
==2646== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==2646==
==2646== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==2646==
==2646== 1 errors in context 1 of 1:
==2646== Invalid read of size 1
==2646== at 0x4E7CF80: vfprintf (in /lib64/libc-2.19.so)
==2646== by 0x4EA67C2: vasprintf (in /lib64/libc-2.19.so)
==2646== by 0x4E85806: asprintf (in /lib64/libc-2.19.so)
==2646== by 0x400623: main (in /home/roel/a.out)
==2646== Address 0x61 is not stack'd, malloc'd or (recently) free'd
==2646==
==2646== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault

Hoe kan ik dit oplossen?

Acties:
  • 0 Henk 'm!

  • expor
  • Registratie: Juni 2005
  • Laatst online: 20-09 10:57
Je char array is niet null terminated (size van 38 weghalen en dan zou dat OK moeten zijn). Daarnaast snap ik niet helemaal wat je nu probeert te printen.

AMD 5800X3D | 16gb DDR 4 @ 3800/14 | 4070 Ti | 1TB Samsung Evo 970, 1TB Samsung Evo 860, 512MB Crucial


Acties:
  • 0 Henk 'm!

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 25-08 11:27
De "%s" impliceren dat er een null termitated string volgt in je argument lijst, maar je geeft een ander type mee. Misschien werkt "%c" ?

[ Voor 11% gewijzigd door epic007 op 26-05-2015 09:07 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Bij "%s" wordt inderdaad een string verwacht (een pointer dus). In de code geef je als argumenten validurlchar[aa] en validurlchar[ab]. Dit zijn beide characters ('a', oftewel ascii code 97). Wat hier feitelijk gebeurt is dat er een string wordt verwacht op adres 97 (0x61 hexadecimaal). Aangezien dit niet het geval is zal dit resulteren in een segmentation fault. De suggestie van epic007 om %c te gebruiken zou mijns inziens moeten werken.

In de compiler uitvoer valt te lezen:
==2646== Address 0x61 is not stack'd, malloc'd or (recently) free'd

[ Voor 12% gewijzigd door Verwijderd op 26-05-2015 12:31 ]


Acties:
  • 0 Henk 'm!

  • Roel911
  • Registratie: Januari 2008
  • Laatst online: 18-08 19:29
Dank voor de reacties, vreemd: programma compiled 1x goed en daarna andere errors:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#include <curl/curl.h>


int main(void)
{
  char aa=0;char ab=0;
  const char validurlchar="abcdefghijklmnopqrstuvwxyz0123456789-_";
  char* source;
  asprintf(&source,"%c%c%.nl",validurlchar[aa],validurlchar[ab]);
  free(source);
}

Bij compilen met: gcc segfault.c -lcurl
Errors:
segfault.c: In function ‘main’:
segfault.c:11:27: warning: initialization makes integer from pointer without a cast [enabled by default]
const char validurlchar="abcdefghijklmnopqrstuvwxyz0123456789-_";
^
segfault.c:13:43: error: subscripted value is neither array nor pointer nor vector
asprintf(&source,"%c%c%.nl",validurlchar[aa],validurlchar[ab]);
^
segfault.c:13:60: error: subscripted value is neither array nor pointer nor vector
asprintf(&source,"%c%c%.nl",validurlchar[aa],validurlchar[ab]);

Hoe kan dat worden opgelost?

[ Voor 50% gewijzigd door Roel911 op 26-05-2015 13:02 ]


Acties:
  • 0 Henk 'm!

  • DrBreakalot
  • Registratie: Oktober 2010
  • Laatst online: 10-09 08:29
Validurlchar is niet 1 char, maar een string, dus je type klopt niet.
Als je dat oplost zijn de andere meldingen ook weg, je probeert nu een element op te halen van een character.

[ Voor 19% gewijzigd door DrBreakalot op 26-05-2015 13:08 ]


Acties:
  • 0 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Ik vond het al onwaarschijnlijk dat het zou kunnen werken:

const char validurlchar[38]="abcdefghijklmnopqrstuvwxyz0123456789-_";
Maak je array minimaal 1 karakter langer zodat de '\0' er ook in kan. Dus 38 tekens + '\0' => minimaal 39

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

  • DrBreakalot
  • Registratie: Oktober 2010
  • Laatst online: 10-09 08:29
Ik gebruik normaal geen c, maar
C:
1
 const char* chars = "abc..."
werkt toch ook? Hoef je niet te tellen

Acties:
  • 0 Henk 'm!

  • Vaan Banaan
  • Registratie: Februari 2001
  • Niet online

Vaan Banaan

Heeft ook Apache ontdekt

Ja dat wilde ik nog in mijn edit zetten, dat is nog beter.

500 "The server made a boo boo"


Acties:
  • 0 Henk 'm!

  • Roel911
  • Registratie: Januari 2008
  • Laatst online: 18-08 19:29
DrBreakalot schreef op dinsdag 26 mei 2015 @ 13:07:
Validurlchar is niet 1 char, maar een string, dus je type klopt niet.
Als je dat oplost zijn de andere meldingen ook weg, je probeert nu een element op te halen van een character.
Het type string kan in C++ gebruikt worden, in C niet ;)

Acties:
  • 0 Henk 'm!

  • EddoH
  • Registratie: Maart 2009
  • Niet online

EddoH

Backpfeifengesicht

Roel911 schreef op dinsdag 26 mei 2015 @ 13:55:
[...]

Het type string kan in C++ gebruikt worden, in C niet ;)
Hij bedoelt dat het type const char fout is voor validurlchar. Het zou const char * (of eigenlijk const char[]) moeten zijn in C.

[ Voor 8% gewijzigd door EddoH op 26-05-2015 14:14 ]


Acties:
  • 0 Henk 'm!

  • Roel911
  • Registratie: Januari 2008
  • Laatst online: 18-08 19:29
DrBreakalot schreef op dinsdag 26 mei 2015 @ 13:19:
Ik gebruik normaal geen c, maar
C:
1
 const char* chars = "abc..."
werkt toch ook? Hoef je niet te tellen
Gedaan, levert hetzelfde problem op.

Acties:
  • 0 Henk 'm!

  • expor
  • Registratie: Juni 2005
  • Laatst online: 20-09 10:57
C:
1
const char* chars = "abc..."
of
C:
1
const char chars[] = "abc..."


Werkt prima. Je moet alleen de % achter %c%c weghalen. De % wordt namelijk geparsed om te vervangen met de meegegeven parameters. Omdat er echter geen type, d/f/F/c/s etc., volgt knalt hij er daar uit. Wil je de % wel afdrukken moet je hem escapen met een tweede %.

[ Voor 41% gewijzigd door expor op 26-05-2015 14:28 ]

AMD 5800X3D | 16gb DDR 4 @ 3800/14 | 4070 Ti | 1TB Samsung Evo 970, 1TB Samsung Evo 860, 512MB Crucial


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22:35
Roel911 schreef op dinsdag 26 mei 2015 @ 13:55:
[...]

Het type string kan in C++ gebruikt worden, in C niet ;)
string, als in "C-style string"
expor schreef op dinsdag 26 mei 2015 @ 14:26:
Werkt prima. Je moet alleen de % achter %c%c weghalen. De % wordt namelijk geparsed om te vervangen met de meegegeven parameters. Omdat er echter geen type, d/f/F/c/s etc., volgt knalt hij er daar uit. Wil je de % wel afdrukken moet je hem escapen met een tweede %.
Over welke code heb je het nu?

[ Voor 61% gewijzigd door farlane op 26-05-2015 15:55 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 00:27

.oisyn

Moderator Devschuur®

Demotivational Speaker

In de topicstart staat
C:
1
asprintf(&source,"%s%s%.nl"


Dus "%s", gevolgd door "%s", gevolgd door "%.nl". Ik gok dat die 3e % sowieso een vergissing is, daar hij tweeletterlige domeinen wilt aflopen. Niet dat hij domeinen met een % erin wilt genereren.

[ Voor 11% gewijzigd door .oisyn op 26-05-2015 19:12 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1