Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C Funktion wird nicht aufgerufen

4 views
Skip to first unread message

Thomas Orgelmacher

unread,
Oct 3, 2018, 10:50:02 AM10/3/18
to
Hallo Zusammen!

Ich stehe auf dem Schlauch. Und zwar richtig.

Ich will mit libexif EXIF-Daten parsen (ok, das ist jetzt nicht wirklich
überraschend).

Folgender Code (Ausschnitt und um den Inhalt von "switch(entry->tag)" gekürzt):

-------------------- schnipp --------------------
void cb_entry(ExifEntry *entry, void *data)
{
exifdata_t *ed = data;

if(! is_suppressed_tag(entry->tag) /* tags we (at least I) don't need */
&& entry->size < BUFFSIZE)
{
exif_entry_get_value(entry, buf, sizeof(buf));

if(!buf[0])
ed = NULL;
else
{
switch(entry->tag)
{
/* lauter cases eben... */
};
}
}
}

void cb_content(ExifContent *content, void *data)
{
exif_content_foreach_entry(content, cb_entry, data);
}
-------------------- schnapp --------------------

Das Problem ist: cb_entry wird nicht aus cb_content von
exif_content_foreach_entry per Callback aufgerufen.
Ich habe mir das im Assembler angeschaut und da steht ganz
klar ein "callq", welches einfach übergangen wird.

Und jetzt wird richtig schräg: gdb meint dazu:
"Line 1 of "exif.c" is at address 0x401fb4 <cb_entry> but contains no code."

Compiler Flags (gcc 5.5) sind "-g -Wall", also wirklich nicht wirklich spannend.

Der Ursprung des Codes ist eine Python3 Extension, die eigentlich auch
weitgehend funktioniert. Ich hatte nur gelegentliche segfaults, die ich
jetzt ohne den Python Kontext isolieren wollte.
Aus dem Grund habe ich die Python Abhängigkeiten wieder ausgebaut und es
tut gar nichts mehr.

Der Code ist kein Geheimnis, wenn jemand mehr sehen will: sachts eben was.

Ich stoße mich vor allem an "<cb_entry> but contains no code." und der
Tatsache, daß das "callq" nicht ausgeführt wird.

Klingelt das bei irgendwem?


Gruß, Thomas


PS.: Entschuldigt bitte den Post an dclc. Ich weiß, daß hier kein C-Problem
vorliegt aber da sitzt Potential, daß ich gern dabei hätte...

--
I have seen things you lusers would not believe. I've seen Sun
monitors on fire off the side of the multimedia lab. I've seen
NTU lights glitter in the dark near the Mail Gate. All these
things will be lost in time, like the root partition last week.

Stefan Reuther

unread,
Oct 3, 2018, 12:21:46 PM10/3/18
to
Am 03.10.2018 um 16:44 schrieb Thomas Orgelmacher:
> -------------------- schnipp --------------------
> void cb_entry(ExifEntry *entry, void *data)
> {
> exifdata_t *ed = data;
>
> if(! is_suppressed_tag(entry->tag) /* tags we (at least I) don't need */

Wie ist denn 'is_suppressed_tag' definiert?

> Das Problem ist: cb_entry wird nicht aus cb_content von
> exif_content_foreach_entry per Callback aufgerufen.
> Ich habe mir das im Assembler angeschaut und da steht ganz
> klar ein "callq", welches einfach übergangen wird.
>
> Und jetzt wird richtig schräg: gdb meint dazu:
> "Line 1 of "exif.c" is at address 0x401fb4 <cb_entry> but contains no
> code."

Wenn du schon im Debugger bist: was sagt denn 'disas cb_entry'?

"Line 1 of exif.c" dürfte ja die Zeile mit dem Funktionskopf sein, dafür
wird wirklich kein Code generiert. Aber 'disas cb_entry' zeigt dir
alles, was er für die Funktion hat.

Wenn der Compiler zu dem Schluss kommt, dass 'is_suppressed_tag' immer
false liefert, wird er z.B. die Funktion 'cb_entry' zu einem einzelnen
'retq'-Befehl zusammenstreichen.


Stefan

Thomas Orgelmacher

unread,
Oct 3, 2018, 1:00:02 PM10/3/18
to
Am 03.10.18 um 17:55 schrieb Stefan Reuther:
>
> Wenn du schon im Debugger bist: was sagt denn 'disas cb_entry'?

Eine ganze Menge:

Dump of assembler code for function cb_entry:
0x0000000000401fb4 <+0>: push %rbp
0x0000000000401fb5 <+1>: mov %rsp,%rbp
0x0000000000401fb8 <+4>: push %r12
0x0000000000401fba <+6>: push %rbx
0x0000000000401fbb <+7>: sub $0x20,%rsp
0x0000000000401fbf <+11>: mov %rdi,-0x28(%rbp)
0x0000000000401fc3 <+15>: mov %rsi,-0x30(%rbp)
0x0000000000401fc7 <+19>: mov -0x30(%rbp),%rax
0x0000000000401fcb <+23>: mov %rax,-0x18(%rbp)
0x0000000000401fcf <+27>: mov 0x20234a(%rip),%rax # 0x604320
<stderr@@GLIBC_2.2.5>
0x0000000000401fd6 <+34>: mov %rax,%rcx
0x0000000000401fd9 <+37>: mov $0x10,%edx
0x0000000000401fde <+42>: mov $0x1,%esi
0x0000000000401fe3 <+47>: mov $0x4029dc,%edi
0x0000000000401fe8 <+52>: callq 0x400f80 <fwrite@plt>
0x0000000000401fed <+57>: mov -0x28(%rbp),%rax
0x0000000000401ff1 <+61>: mov (%rax),%eax
0x0000000000401ff3 <+63>: mov %eax,%edi
0x0000000000401ff5 <+65>: callq 0x401988 <is_suppressed_tag>
0x0000000000401ffa <+70>: test %eax,%eax
0x0000000000401ffc <+72>: jne 0x4021ea <cb_entry+566>
0x0000000000402002 <+78>: mov -0x28(%rbp),%rax
0x0000000000402006 <+82>: mov 0x18(%rax),%eax
0x0000000000402009 <+85>: cmp $0x7fff,%eax
0x000000000040200e <+90>: ja 0x4021ea <cb_entry+566>
0x0000000000402014 <+96>: mov -0x28(%rbp),%rax
0x0000000000402018 <+100>: mov $0x8000,%edx
0x000000000040201d <+105>: mov $0x604360,%esi
0x0000000000402022 <+110>: mov %rax,%rdi
0x0000000000402025 <+113>: callq 0x400e20 <exif_entry_get_value@plt>
0x000000000040202a <+118>: mov -0x28(%rbp),%rax
0x000000000040202e <+122>: mov 0x18(%rax),%ebx
0x0000000000402031 <+125>: mov -0x28(%rbp),%rax
0x0000000000402035 <+129>: mov 0x4(%rax),%eax
0x0000000000402038 <+132>: mov %eax,%edi
0x000000000040203a <+134>: callq 0x400ef0 <exif_format_get_name@plt>
0x000000000040203f <+139>: mov %rax,%r12
0x0000000000402042 <+142>: mov -0x28(%rbp),%rax
0x0000000000402046 <+146>: mov (%rax),%eax
0x0000000000402048 <+148>: mov %eax,%edi
0x000000000040204a <+150>: callq 0x400e70 <exif_tag_get_name@plt>
0x000000000040204f <+155>: mov %rax,%rdx
0x0000000000402052 <+158>: mov -0x28(%rbp),%rax
0x0000000000402056 <+162>: mov (%rax),%eax
0x0000000000402058 <+164>: mov $0x604360,%r9d
0x000000000040205e <+170>: mov %ebx,%r8d
0x0000000000402061 <+173>: mov %r12,%rcx
0x0000000000402064 <+176>: mov %eax,%esi
0x0000000000402066 <+178>: mov $0x4029ed,%edi
0x000000000040206b <+183>: mov $0x0,%eax
0x0000000000402070 <+188>: callq 0x400e50 <printf@plt>
0x0000000000402075 <+193>: movzbl 0x2022e4(%rip),%eax # 0x604360 <buf>
0x000000000040207c <+200>: test %al,%al
0x000000000040207e <+202>: jne 0x40208d <cb_entry+217>
0x0000000000402080 <+204>: movq $0x0,-0x18(%rbp)
0x0000000000402088 <+212>: jmpq 0x4021ea <cb_entry+566>
0x000000000040208d <+217>: mov -0x28(%rbp),%rax
0x0000000000402091 <+221>: mov (%rax),%eax
0x0000000000402093 <+223>: cmp $0x132,%eax
0x0000000000402098 <+228>: je 0x4021b2 <cb_entry+510>
0x000000000040209e <+234>: cmp $0x132,%eax
0x00000000004020a3 <+239>: ja 0x4020c3 <cb_entry+271>
0x00000000004020a5 <+241>: cmp $0x110,%eax
0x00000000004020aa <+246>: je 0x402100 <cb_entry+332>
0x00000000004020ac <+248>: cmp $0x131,%eax
0x00000000004020b1 <+253>: je 0x40211c <cb_entry+360>
0x00000000004020b3 <+255>: cmp $0x10f,%eax
0x00000000004020b8 <+260>: je 0x40214b <cb_entry+407>
0x00000000004020be <+266>: jmpq 0x4021ea <cb_entry+566>
0x00000000004020c3 <+271>: cmp $0x9004,%eax
0x00000000004020c8 <+276>: je 0x40218a <cb_entry+470>
0x00000000004020ce <+282>: cmp $0x9004,%eax
0x00000000004020d3 <+287>: ja 0x4020e5 <cb_entry+305>
0x00000000004020d5 <+289>: cmp $0x9003,%eax
0x00000000004020da <+294>: je 0x402171 <cb_entry+445>
0x00000000004020e0 <+300>: jmpq 0x4021ea <cb_entry+566>
0x00000000004020e5 <+305>: cmp $0xa002,%eax
0x00000000004020ea <+310>: je 0x4021da <cb_entry+550>
0x00000000004020f0 <+316>: cmp $0xa003,%eax
0x00000000004020f5 <+321>: je 0x4021dd <cb_entry+553>
0x00000000004020fb <+327>: jmpq 0x4021ea <cb_entry+566>
0x0000000000402100 <+332>: mov -0x18(%rbp),%rax
0x0000000000402104 <+336>: add $0x100,%rax
0x000000000040210a <+342>: mov $0x604360,%esi
0x000000000040210f <+347>: mov %rax,%rdi
0x0000000000402112 <+350>: callq 0x400e10 <strcpy@plt>
0x0000000000402117 <+355>: jmpq 0x4021ea <cb_entry+566>
0x000000000040211c <+360>: mov -0x18(%rbp),%rax
0x0000000000402120 <+364>: movzbl 0x100(%rax),%eax
0x0000000000402127 <+371>: test %al,%al
0x0000000000402129 <+373>: jne 0x4021e0 <cb_entry+556>
0x000000000040212f <+379>: mov -0x18(%rbp),%rax
0x0000000000402133 <+383>: add $0x100,%rax
0x0000000000402139 <+389>: mov $0x604360,%esi
0x000000000040213e <+394>: mov %rax,%rdi
0x0000000000402141 <+397>: callq 0x400e10 <strcpy@plt>
0x0000000000402146 <+402>: jmpq 0x4021e0 <cb_entry+556>
0x000000000040214b <+407>: mov -0x18(%rbp),%rax
0x000000000040214f <+411>: movzbl 0x100(%rax),%eax
0x0000000000402156 <+418>: test %al,%al
0x0000000000402158 <+420>: jne 0x4021e3 <cb_entry+559>
0x000000000040215e <+426>: mov -0x18(%rbp),%rax
0x0000000000402162 <+430>: mov $0x604360,%esi
0x0000000000402167 <+435>: mov %rax,%rdi
0x000000000040216a <+438>: callq 0x400e10 <strcpy@plt>
0x000000000040216f <+443>: jmp 0x4021e3 <cb_entry+559>
0x0000000000402171 <+445>: mov -0x18(%rbp),%rax
0x0000000000402175 <+449>: add $0x200,%rax
0x000000000040217b <+455>: mov $0x604360,%esi
0x0000000000402180 <+460>: mov %rax,%rdi
0x0000000000402183 <+463>: callq 0x400e10 <strcpy@plt>
0x0000000000402188 <+468>: jmp 0x4021ea <cb_entry+566>
0x000000000040218a <+470>: mov -0x18(%rbp),%rax
0x000000000040218e <+474>: movzbl 0x200(%rax),%eax
0x0000000000402195 <+481>: test %al,%al
0x0000000000402197 <+483>: jne 0x4021e6 <cb_entry+562>
0x0000000000402199 <+485>: mov -0x18(%rbp),%rax
0x000000000040219d <+489>: add $0x200,%rax
0x00000000004021a3 <+495>: mov $0x604360,%esi
0x00000000004021a8 <+500>: mov %rax,%rdi
0x00000000004021ab <+503>: callq 0x400e10 <strcpy@plt>
0x00000000004021b0 <+508>: jmp 0x4021e6 <cb_entry+562>
0x00000000004021b2 <+510>: mov -0x18(%rbp),%rax
0x00000000004021b6 <+514>: movzbl 0x200(%rax),%eax
0x00000000004021bd <+521>: test %al,%al
0x00000000004021bf <+523>: jne 0x4021e9 <cb_entry+565>
0x00000000004021c1 <+525>: mov -0x18(%rbp),%rax
0x00000000004021c5 <+529>: add $0x200,%rax
0x00000000004021cb <+535>: mov $0x604360,%esi
0x00000000004021d0 <+540>: mov %rax,%rdi
0x00000000004021d3 <+543>: callq 0x400e10 <strcpy@plt>
0x00000000004021d8 <+548>: jmp 0x4021e9 <cb_entry+565>
0x00000000004021da <+550>: nop
0x00000000004021db <+551>: jmp 0x4021ea <cb_entry+566>
0x00000000004021dd <+553>: nop
0x00000000004021de <+554>: jmp 0x4021ea <cb_entry+566>
0x00000000004021e0 <+556>: nop
0x00000000004021e1 <+557>: jmp 0x4021ea <cb_entry+566>
0x00000000004021e3 <+559>: nop
0x00000000004021e4 <+560>: jmp 0x4021ea <cb_entry+566>
0x00000000004021e6 <+562>: nop
0x00000000004021e7 <+563>: jmp 0x4021ea <cb_entry+566>
0x00000000004021e9 <+565>: nop
0x00000000004021ea <+566>: nop
0x00000000004021eb <+567>: add $0x20,%rsp
0x00000000004021ef <+571>: pop %rbx
0x00000000004021f0 <+572>: pop %r12
0x00000000004021f2 <+574>: pop %rbp
0x00000000004021f3 <+575>: retq
End of assembler dump.



> "Line 1 of exif.c" dürfte ja die Zeile mit dem Funktionskopf sein, dafür
> wird wirklich kein Code generiert. Aber 'disas cb_entry' zeigt dir
> alles, was er für die Funktion hat.
>
> Wenn der Compiler zu dem Schluss kommt, dass 'is_suppressed_tag' immer
> false liefert, wird er z.B. die Funktion 'cb_entry' zu einem einzelnen
> 'retq'-Befehl zusammenstreichen.

int is_suppressed_tag(int tag)
{
static int suppressed_tags[] =
{
EXIF_TAG_PRINT_IMAGE_MATCHING,
EXIF_TAG_MAKER_NOTE,
EXIF_TAG_XP_KEYWORDS,
EXIF_TAG_USER_COMMENT,
EXIF_TAG_COPYRIGHT,
EXIF_TAG_PADDING,
EXIF_TAG_XP_SUBJECT,
EXIF_TAG_XP_KEYWORDS,
EXIF_TAG_XP_AUTHOR,
EXIF_TAG_XP_COMMENT,
EXIF_TAG_XP_TITLE,
EXIF_TAG_DEVICE_SETTING_DESCRIPTION,
EXIF_TAG_IMAGE_DESCRIPTION,
-1
};

for(int i = 0; suppressed_tags[i] != -1; i++)
if(suppressed_tags[i] == tag)
return 1;

return 0;
}


Ich sehe nicht, was da mal eben wegoptimiert werden könnte...


Gruß, Thomas

Edzard Egberts

unread,
Oct 4, 2018, 2:23:15 AM10/4/18
to
Thomas Orgelmacher wrote:
> Hallo Zusammen!
>
> Ich stehe auf dem Schlauch. Und zwar richtig.
>
> Ich will mit libexif EXIF-Daten parsen (ok, das ist jetzt nicht wirklich
> überraschend).
>
> Folgender Code (Ausschnitt und um den Inhalt von "switch(entry->tag)"
> gekürzt):
>
> -------------------- schnipp --------------------
> void cb_entry(ExifEntry *entry, void *data)
> {
>    exifdata_t *ed = data;
>
>    if(! is_suppressed_tag(entry->tag) /* tags we (at least I) don't
> need */
>       && entry->size < BUFFSIZE)
>      {
>         exif_entry_get_value(entry, buf, sizeof(buf));
>
>         if(!buf[0])
>           ed = NULL;
>         else
>           {
>              switch(entry->tag)
>                {
>                /* lauter cases eben... */
>                };
>           }
>      }
> }
>
> void cb_content(ExifContent *content, void *data)
> {
>    exif_content_foreach_entry(content, cb_entry, data);
> }
> -------------------- schnapp --------------------
>
> Das Problem ist: cb_entry wird nicht aus cb_content von
> exif_content_foreach_entry per Callback aufgerufen.

Wenn es eben nicht geht, kannst Du den ExifContent doch auch direkt parsen:

for (unsigned i= 0; i< content->count; ++i)
cb_entry((*content)[i], nullptr);

Das müsste Dir zeigen, ob exif_content_foreach_entry() kaputt ist, oder
das Problem tatsächlich im cb_entry() liegt.

Thomas Orgelmacher

unread,
Oct 4, 2018, 1:20:03 PM10/4/18
to
Am 04.10.18 um 08:22 schrieb Edzard Egberts:
>
> Wenn es eben nicht geht, kannst Du den ExifContent doch auch direkt parsen:
>
> for (unsigned i= 0; i< content->count; ++i)
>     cb_entry((*content)[i], nullptr);
>
> Das müsste Dir zeigen, ob exif_content_foreach_entry() kaputt ist, oder das
> Problem tatsächlich im cb_entry() liegt.

Meine Güte, man kann ja sowas von daneben sein...

Wenn man exif_data_new_from_data(mapped, size) mit size = 0 aufruft, findet
es tatsächlich nichts... unglaublich :-)

Vielen Dank an alle für's Schubsen!

Thomas
0 new messages