Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C/libpq] Crash bij aanroepen PQexec

Pagina: 1
Acties:

  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Mijn programma crasht soms bij het aanroepen van PQexec. Het vreemde is het soms helemaal niet crasht en als het crasht dan crasht het altijd op verschillende queries. Het is dus niet een specifieke query die de boel onderuit haalt.

De functie waar het mis gaat.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
long    load_group(struct nntp_group *group)
{
    char        db_query[1024];
    PGresult    *db_result;
    int     col_group_id;
    long        col_highest, article_count;

    sprintf(db_query, "SELECT * FROM load_group('%s', %ld, %ld);", group->group_name, group->lowest, group->highest);

    db_result   =   PQexec(db_conn, db_query);

    if (PQresultStatus(db_result) == PGRES_TUPLES_OK) {
        // retrieve column numbers
        col_group_id    =   PQfnumber(db_result, "group_id");
        col_highest =   PQfnumber(db_result, "highest");

        group->db_id    =   atoi(PQgetvalue(db_result, 0, col_group_id));
        group->lowest   =   atol(PQgetvalue(db_result, 0, col_highest));

        article_count   =   group->highest - group->lowest + 1;

        PQclear(db_result);
        return article_count;
    } else {
        return -1;
    }
}


db_conn is buiten de functie gedefiniëerd. Een backtrace geeft het volgende:
Program received signal SIGSEGV, Segmentation fault.
0x001bc83e in ?? () from /lib/tls/i686/cmov/libc.so.6
(gdb) backtrace
#0 0x001bc83e in ?? () from /lib/tls/i686/cmov/libc.so.6
#1 0x001beafd in ?? () from /lib/tls/i686/cmov/libc.so.6
#2 0x001c0f9c in malloc () from /lib/tls/i686/cmov/libc.so.6
#3 0x00139617 in ?? () from /usr/lib/libpq.so.5
#4 0x0014531f in ?? () from /usr/lib/libpq.so.5
#5 0x0013a868 in ?? () from /usr/lib/libpq.so.5
#6 0x0013c541 in PQgetResult () from /usr/lib/libpq.so.5
#7 0x0013c800 in ?? () from /usr/lib/libpq.so.5
#8 0x08048cdf in load_group (group=0x8066468) at db.c:29
#9 0x08049293 in nntp_process_group (groups=0x804c038, group_line=0x80558dd "msn.forums.outdoors.recreation.general") at nntp.c:138
#10 0x0804913a in nntp_list (connection=0x8055890, groups=0x804c038) at nntp.c:105
#11 0x080495bb in main () at main.c:48
PQgetResult is een functie die door libpq intern wordt aangeroepen van de functie PQexec. Regel 28 in db.c is de regel die PQexec aanroept.

Ik heb werkelijk geen idee wat het probleem kan zijn. db_conn is een geldige verbinding naar PostgreSQL, db_query is een geldige query (en anders zou dat ook niet het programma moeten kunnen crashen). Enig idee wat ik hier fout doe?

Ik ontken het bestaan van IE.


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
Het is een segfault, dus ergens gaat er iets mis met het geheugen (een gekke (of geen) malloc of free op iets dat niet bestaat of dingen ergens naartoe gekopieerd wat niet klopt of een array index gebruikt die niet bestaat?

Het kan heel ergens anders zitten dan je denkt of nu zoek, maar dat het probleem geheugen corrupt maakt dat PQexec gebruikt. Of een van de buffers/pointers die je voor PQexec gebruikt is verkeerd (en soms is het geheugen waar deze naar refereert wel geldig, en soms niet).

Edit: is het altijd regel 10 waar het fout gaat?

[ Voor 4% gewijzigd door roy-t op 18-06-2010 14:13 ]

~ Mijn prog blog!


  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
Ja, het is altijd dezelfde regel waar het misloopt. Altijd de regel waar ik PQexec aanroep. Ik weet 100% zeker dat de query die ik doorgeef goed is, de pointer db_conn blijft ook gewoon netjes hetzelfde.

Ik heb om te testen een simpele functie gemaakt, load_all_groups
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
long    load_all_groups(struct nntp_groups *groups)
{
    struct      nntp_group  *group;
    long        article_count;

    group           =   groups->first;
    article_count   =   0;

    while (group != NULL) {
        article_count   +=  load_group(group);
        group           =   group->next;
    }

    return article_count;
}


Hierbij wordt simpel door de lijst 'group' heengelopen, zonder ook maar ergens iets aan te passen. Het probleem blijft hetzelfde Het gekke is wat ik gemerkt heb is dat als het programma niet crashed in de eerste seconde dat het de load_group functies gaat uitvoeren het verder ook niet crashed.

Ik ontken het bestaan van IE.


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
Kloppen groups->first; en group->next; altijd, is je buffer db_query wel groot genoeg (misschien zijn er wat gekke te lange namen?). En probeer anders eens vlak vooor het aanroepen van PQexec nog even alle parameters die je gebruikt te printen (of heb je dit al gedaan door de query te printen?).

Ik kan zo niets fouts vinden iig.

~ Mijn prog blog!


  • cyberstalker
  • Registratie: September 2005
  • Niet online

cyberstalker

Eersteklas beunhaas

Topicstarter
roy-t schreef op vrijdag 18 juni 2010 @ 15:01:
Kloppen groups->first; en group->next; altijd, is je buffer db_query wel groot genoeg (misschien zijn er wat gekke te lange namen?). En probeer anders eens vlak vooor het aanroepen van PQexec nog even alle parameters die je gebruikt te printen (of heb je dit al gedaan door de query te printen?).

Ik kan zo niets fouts vinden iig.
groups->first en group->next kloppen. Ik kan zonder enig probleem door de hele lijst heenlopen en gegevens gebruiken. De query klopt ook (heb ik al getest door de query te printen voor het aanroepen van de functie), zo ook de pointer db_conn.

Er is ook geen probleem met te gekke lange namen, de langste naam is 127 tekens lang en sowieso, anders zou de query niet kloppen.

[ Voor 8% gewijzigd door cyberstalker op 18-06-2010 15:07 ]

Ik ontken het bestaan van IE.


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
Hmm ja dat dacht ik al, ik bleef maar dingen roepen voor het geval dat je iets over het hoofd had gezien. Heb je je programma al door VALGRIND of een andere tool gegooid om naar meer fouten te sporen?

edit Valgrind niet Falgrind, thx H!GHGuY

[ Voor 10% gewijzigd door roy-t op 19-06-2010 12:13 ]

~ Mijn prog blog!


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

roy-t schreef op vrijdag 18 juni 2010 @ 15:55:
Hmm ja dat dacht ik al, ik bleef maar dingen roepen voor het geval dat je iets over het hoofd had gezien. Heb je je programma al door FALGRIND of een andere tool gegooid om naar meer fouten te sporen?
googlen op valgrind zal je wel iets meer resultaten geven. Mocht je op een exotische architectuur zitten dan is er ook nog mfence enz.

ASSUME makes an ASS out of U and ME


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 30-11 00:17
1 db_conn is kapot
2 db_query is kapot ( dubbel check ff wat uit die sprintf zou moeten komen: is %s/%ld echt wel het correcte format? )
3 db_result is kapot Overschrijf je mischien hier iets doordat je over de grenzen van db_query gaat?

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.


  • Onno
  • Registratie: Juni 1999
  • Niet online
farlane schreef op zaterdag 19 juni 2010 @ 02:33:
db_result is kapot Overschrijf je mischien hier iets doordat je over de grenzen van db_query gaat?
Het lijkt me niet dat dat hier een fout kan geven: zelfs als db_result door sprintf wordt overschreven (maar waarschijnlijk staan ze daarvoor in de verkeerde volgorde op de stack) dan heeft PQexec daar geen last van, en na afloop wordt de waarde gewoon overschreven door het resultaat van PQexec en is er dus ook niets meer aan de hand.

Om dat soort problemen (en de nodige andere) te voorkomen kun je als je waarden aan een query wilt meegeven overigens wel altijd beter PQexecParams in plaats van sprintf + PQexec gebruiken, en anders op z'n minst snprintf.
cyberstalker schreef op vrijdag 18 juni 2010 @ 14:50:
Ja, het is altijd dezelfde regel waar het misloopt. Altijd de regel waar ik PQexec aanroep. Ik weet 100% zeker dat de query die ik doorgeef goed is, de pointer db_conn blijft ook gewoon netjes hetzelfde.
Dat de pointer dezelfde waarde houdt wil niet zeggen dat de inhoud van de structuur waar hij naar wijst ook nog steeds klopt. Het kan prima zo zijn dat daar per ongeluk iets overschreven is waardoor de boel stuk gaat.

Je zou kunnen proberen om direct voor deze PQexec-aanroep een nieuwe connectie te openen en die te gebruiken, als het dan niet meer fout gaat lijkt het me toch echt dat er iets met je db_conn mis is.
Pagina: 1