Bug#907862: gtkpod segfaults on startup
Hello,
just tried to get some more information from this backtrace.
This is what I assume the last frames look like when not optimizing:
g_type_check_value_holds
playcounts_plist_read, line 1115
playcounts_init
itdb_parse_internal
...
main
playcounts_plist_read:
...
1114 for (i = 0; i < array->len; i++) {
1115 if (!G_VALUE_HOLDS (g_array_index (array, GValue *, i), G_TYPE_HASH_TABLE)) {
1116 continue;
...
Unfortunately without having the hardware and debugging a live process
or getting a core dump, investigation would stop here.
One can let create core dumps by installing the systemd-coredump package.
Kind regards,
Bernhard
# from the bug report:
(gdb) bt
#0 0x00007ffff652b57d in g_type_check_value_holds () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#1 0x00007ffff5da5319 in () at /usr/lib/x86_64-linux-gnu/libgpod.so.4
#2 0x00007ffff5daa1f3 in itdb_parse () at /usr/lib/x86_64-linux-gnu/libgpod.so.4
#3 0x00007ffff7d6268d in gp_import_itdb () at /usr/lib/x86_64-linux-gnu/libgtkpod.so.1
#4 0x00007ffff7d63268 in gp_load_ipod () at /usr/lib/x86_64-linux-gnu/libgtkpod.so.1
#5 0x00007ffff7d7b64f in () at /usr/lib/x86_64-linux-gnu/libgtkpod.so.1
#6 0x00007ffff6c790a0 in () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#7 0x00007ffff622bb73 in () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#8 0x00007ffff622b0f5 in g_main_context_dispatch () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#9 0x00007ffff622b4c0 in () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#10 0x00007ffff622b7d2 in g_main_loop_run () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#11 0x00007ffff7171e85 in gtk_main () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#12 0x000055555555c833 in main ()
apt install xserver-xorg sddm openbox gdb gtkpod-dbg libgtk-3-0-dbgsym libglib2.0-0-dbgsym libgtk-3-0-dbgsym libgpod4-dbgsym
apt install dpkg-dev devscripts
mkdir libgpod4/orig -p
cd libgpod4/orig
apt source libgpod4
cd ../..
export DISPLAY=:0
gdb -q --args gtkpod
set height 0
set width 0
set pagination off
directory /home/benutzer/libgpod4/orig/libgpod-0.8.3/bindings/python/examples
run
disassemble main
disassemble gtk_main
disassemble g_main_loop_run
disassemble g_main_context_iterate
disassemble g_main_context_dispatch
disassemble 0x00007ffff622bb73-0x20,+0x00007ffff622bb73+0x10
disassemble gp_load_ipod
disassemble gp_import_itdb
disassemble itdb_parse
disassemble itdb_parse_internal
disassemble g_type_check_value_holds
#0 0x00007ffff636057d <+61>: testb $0x8,0x16(%rbx)
#1 0x00007ffff5bda314 <+4676>: callq 0x7ffff5bc9540 <g_type_check_value_holds@plt>
0x00007ffff5bda319 <+4681>: test %eax,%eax
#2 0x00007ffff5bdf1ee <+78>: callq 0x7ffff5bd90d0 <itdb_parse_internal>
0x00007ffff5bdf1f3 <+83>: mov %rbx,%rdi
#3 0x00007ffff7d94688 <+552>: callq 0x7ffff7d84b50 <itdb_parse@plt>
0x00007ffff7d9468d <+557>: mov %rax,%rbp
#4 0x00007ffff7d95263 <+547>: callq 0x7ffff7d85130 <gp_import_itdb@plt>
0x00007ffff7d95268 <+552>: mov %rax,%r13
#5 ???
#6 ???
#7 ???
#8 0x00007ffff60600f3 <+339>: callq *%rax ???
0x00007ffff60600f5 <+341>: mov 0x18(%rsp),%rcx
#9 0x00007ffff60604bb <+507>: callq 0x7ffff605ffa0 <g_main_context_dispatch>
0x00007ffff60604c0 <+512>: jmpq 0x7ffff60603ee <g_main_context_iterate+302>
#10 0x00007ffff60607cd <+189>: callq 0x7ffff60602c0 <g_main_context_iterate>
0x00007ffff60607d2 <+194>: mov 0x8(%rbx),%eax
#11 0x00007ffff6fa6e80 <+128>: callq 0x7ffff6dfe110 <g_main_loop_run@plt>
0x00007ffff6fa6e85 <+133>: callq 0x7ffff6dff6f0 <gdk_threads_enter@plt>
#12 0x000055555555c82e <+286>: callq 0x55555555b610 <gtk_main@plt>
0x000055555555c833 <+291>: xor %eax,%eax
disassemble /m 0x00007ffff5bda314-0x100,0x00007ffff5bda314+0x20
...
1114 for (i = 0; i < array->len; i++) {
0x00007ffff5bda2d4 <itdb_parse_internal+4612>: mov 0x8(%rax),%ecx
0x00007ffff5bda2d7 <itdb_parse_internal+4615>: test %ecx,%ecx
0x00007ffff5bda2d9 <itdb_parse_internal+4617>: je 0x7ffff5bda472 <itdb_parse_internal+5026>
0x00007ffff5bda2df <itdb_parse_internal+4623>: mov %r13,0x38(%rsp)
0x00007ffff5bda2e4 <itdb_parse_internal+4628>: mov 0x30(%rsp),%r13
0x00007ffff5bda2e9 <itdb_parse_internal+4633>: mov %rax,%rbp
0x00007ffff5bda2ec <itdb_parse_internal+4636>: mov %ebx,0x30(%rsp)
0x00007ffff5bda2f0 <itdb_parse_internal+4640>: mov %r12,0x40(%rsp)
0x00007ffff5bda2f5 <itdb_parse_internal+4645>: nopl (%rax)
1115 if (!G_VALUE_HOLDS (g_array_index (array, GValue *, i), G_TYPE_HASH_TABLE)) {
0x00007ffff5bda2f8 <itdb_parse_internal+4648>: mov 0x0(%rbp),%rax
0x00007ffff5bda2fc <itdb_parse_internal+4652>: mov (%rax,%r14,8),%rbx
0x00007ffff5bda300 <itdb_parse_internal+4656>: test %rbx,%rbx
0x00007ffff5bda303 <itdb_parse_internal+4659>: je 0x7ffff5bda456 <itdb_parse_internal+4998>
0x00007ffff5bda309 <itdb_parse_internal+4665>: cmp (%rbx),%r13
0x00007ffff5bda30c <itdb_parse_internal+4668>: je 0x7ffff5bda321 <itdb_parse_internal+4689>
0x00007ffff5bda30e <itdb_parse_internal+4670>: mov %r13,%rsi
0x00007ffff5bda311 <itdb_parse_internal+4673>: mov %rbx,%rdi
0x00007ffff5bda314 <itdb_parse_internal+4676>: callq 0x7ffff5bc9540 <g_type_check_value_holds@plt>
0x00007ffff5bda319 <itdb_parse_internal+4681>: test %eax,%eax
0x00007ffff5bda31b <itdb_parse_internal+4683>: je 0x7ffff5bda456 <itdb_parse_internal+4998>
1116 continue;
1117 }
1118
1119 track_dict = g_value_get_boxed (g_array_index (array, GValue *, i));
./src/itdb_itunesdb.c:
(gdb) list itdb_parse_internal
3227
3228 static gboolean
3229 itdb_parse_internal (Itdb_iTunesDB *itdb, gboolean compressed, GError **error)
3230 {
3231 FImport *fimp;
3232 gboolean success = FALSE;
3233
3234 g_return_val_if_fail (itdb->filename != NULL, FALSE);
3235
3236 fimp = g_new0 (FImport, 1);
3237 fimp->itdb = itdb;
3238
3239 fimp->fcontents = fcontents_read (itdb->filename, error);
3240
3241 if (fimp->fcontents)
3242 {
3243 itdb_hash72_extract_hash_info (fimp->itdb->device,
3244 (guchar *)fimp->fcontents->contents,
3245 fimp->fcontents->length);
3246 if (!playcounts_init (fimp))
3247 {
3248 g_warning ("Error parsing recent playcounts");
3249 }
3250 if (parse_fimp (fimp, compressed))
3251 {
3252 if (read_OTG_playlists (fimp))
3253 {
3254 success = TRUE;
3255 }
3256 }
3257 }
3258
3259 if (fimp->error)
3260 g_propagate_error (error, fimp->error);
3261
3262 itdb_free_fimp (fimp);
3263
3264 return success;
3265 }
(gdb) list 1183
1178 * the same purpose.
1179 *
1180 * Returns TRUE on success (also when no Play Count
1181 * file is found as this is not an error) and FALSE otherwise, in
1182 * which case fimp->error is set accordingly. */
1183 static gboolean playcounts_init (FImport *fimp)
1184 {
1185 const gchar *plc[] = {"Play Counts", NULL};
1186 const gchar *ist[] = {"iTunesStats", NULL};
1187 const gchar *plcpl[] = {"PlayCounts.plist", NULL};
1188 gchar *plcname, *dirname, *istname, *plcplname;
1189 gboolean result=TRUE;
1190 struct stat filestat;
1191 FContents *cts;
1192 GValue *plist_data;
1193
1194 g_return_val_if_fail (fimp, FALSE);
1195 g_return_val_if_fail (!fimp->error, FALSE);
1196 g_return_val_if_fail (!fimp->playcounts, FALSE);
1197 g_return_val_if_fail (fimp->itdb, FALSE);
1198 g_return_val_if_fail (fimp->itdb->filename, FALSE);
1199
1200 dirname = g_path_get_dirname (fimp->itdb->filename);
1201
1202 plcname = itdb_resolve_path (dirname, plc);
1203 istname = itdb_resolve_path (dirname, ist);
1204 plcplname = itdb_resolve_path (dirname, plcpl);
1205
1206 g_free (dirname);
1207
1208 /* skip if no playcounts file is present */
1209 if (plcname)
1210 {
1211 /* skip if playcounts file has zero-length (often happens after
1212 * dosfsck) */
1213 stat (plcname, &filestat);
1214 if (filestat.st_size >= 0x60)
1215 {
1216 cts = fcontents_read (plcname, &fimp->error);
1217 if (cts)
1218 {
1219 result = playcounts_read (fimp, cts);
1220 fcontents_free (cts);
1221 }
1222 else
1223 {
1224 result = FALSE;
1225 }
1226 }
1227 }
1228 else if (istname)
1229 {
1230 /* skip if iTunesStats file has zero-length (often happens after
1231 * dosfsck) */
1232 stat (istname, &filestat);
1233 if (filestat.st_size >= 0x06)
1234 {
1235 cts = fcontents_read (istname, &fimp->error);
1236 if (cts)
1237 {
1238 result = itunesstats_read (fimp, cts);
1239 fcontents_free (cts);
1240 }
1241 else
1242 {
1243 result = FALSE;
1244 }
1245 }
1246 }
1247 else if (plcplname)
1248 {
1249 /* skip if PlayCounts.plist file has zero-length */
1250 stat (plcplname, &filestat);
1251 if (filestat.st_size > 0)
1252 {
1253 plist_data = itdb_plist_parse_from_file (plcplname, &fimp->error);
1254 if (plist_data)
1255 {
1256 result = playcounts_plist_read (fimp, plist_data);
1257 g_value_unset (plist_data);
1258 }
1259 else
1260 {
1261 result = FALSE;
1262 }
1263 }
1264 }
1265
1266 g_free (plcname);
1267 g_free (istname);
1268 g_free (plcplname);
1269
1270 return result;
1271 }
1088 /* called by playcounts_init */
1089 static gboolean playcounts_plist_read (FImport *fimp, GValue *plist_data)
1090 {
1091 GHashTable *playcounts;
1092 struct playcount *playcount;
1093 GHashTable *pc_dict, *track_dict;
1094 GValue *to_parse;
1095 GArray *array;
1096 gint i;
1097 guint32 mac_time;
1098 guint64 *dbid;
1099
1100 g_return_val_if_fail (G_VALUE_HOLDS (plist_data, G_TYPE_HASH_TABLE), FALSE);
1101 pc_dict = g_value_get_boxed (plist_data);
1102
1103 to_parse = g_hash_table_lookup (pc_dict, "tracks");
1104 if (to_parse == NULL) {
1105 return FALSE;
1106 }
1107 if (!G_VALUE_HOLDS (to_parse, G_TYPE_ARRAY)) {
1108 return FALSE;
1109 }
1110
1111 playcounts = g_hash_table_new_full (g_int64_hash, g_int64_equal, g_free, g_free);
1112
1113 array = (GArray*)g_value_get_boxed (to_parse);
1114 for (i = 0; i < array->len; i++) {
1115 if (!G_VALUE_HOLDS (g_array_index (array, GValue *, i), G_TYPE_HASH_TABLE)) {
1116 continue;
1117 }
1118
1119 track_dict = g_value_get_boxed (g_array_index (array, GValue *, i));
1120 if (track_dict == NULL)
1121 continue;
1122
1123 to_parse = g_hash_table_lookup (track_dict, "persistentID");
1124 if (!to_parse)
1125 continue;
1126
1127 dbid = g_new0 (guint64, 1);
1128 if (!G_VALUE_HOLDS (to_parse, G_TYPE_INT64))
1129 continue;
1130 *dbid = g_value_get_int64 (to_parse);
1131 playcount = g_new0 (struct playcount, 1);
1132 g_hash_table_insert (playcounts, dbid, playcount);
1133
1134 playcount->bookmark_time = playcounts_plist_get_gint64 (track_dict, "bookmarkTimeInMS");
1135 playcount->playcount = playcounts_plist_get_gint64 (track_dict, "playCount");
1136 mac_time = playcounts_plist_get_gint64 (track_dict, "playMacOSDate");
1137 playcount->time_played = device_time_mac_to_time_t (fimp->itdb->device, mac_time);
1138 playcount->skipcount = playcounts_plist_get_gint64 (track_dict, "skipCount");
1139 mac_time = playcounts_plist_get_gint64 (track_dict, "skipMacOSDate");
1140 playcount->last_skipped = device_time_mac_to_time_t (fimp->itdb->device, mac_time);
1141 playcount->rating = playcounts_plist_get_gint64 (track_dict, "userRating");
1142 if (!playcount->rating)
1143 playcount->rating = NO_PLAYCOUNT;
1144
1145 to_parse = g_hash_table_lookup (track_dict, "playedState");
1146 if (to_parse && G_VALUE_HOLDS (to_parse, G_TYPE_BOOLEAN)) {
1147 ; /* What do we do with this? */
1148 }
1149 }
1150 fimp->pcounts2 = playcounts;
1151 return TRUE;
1152 }
1
Reply to: