I had some odd issues downloading from my Petrel 2, so I tried running dctool download directly to better diagnose it, and saw glibc complaining about corrupt FILE* data.
This got me running in circles for a while, but eventually I figured out something corrupted the pointer and debugged what:
(gdb) break dctool_xml_output_write
Breakpoint 1 at 0x55555556b4c2: file ../../libdivecomputer/examples/output_xml.c, line 233.
(next a bit until sampledata.ostream is set , sampledata.ostream = output->ostream; and then watch it )
(gdb) watch sampledata.ostream
Hardware watchpoint 2: sampledata.ostream
Old value = (FILE *) 0x555555644210
New value = (FILE *) 0x555555644201
shearwater_predator_parser_samples_foreach (abstract=0x55555565ba80, callback=0x55555556acd9 <sample_cb>, userdata=0x7fffffffd5f0)
at ../../libdivecomputer/src/shearwater_predator_parser.c:1232
1232 if (parser->needs_divecan_calibration_estimate) {
(gdb) where
#0 shearwater_predator_parser_samples_foreach (abstract=0x55555565ba80, callback=0x55555556acd9 <sample_cb>, userdata=0x7fffffffd5f0)
at ../../libdivecomputer/src/shearwater_predator_parser.c:1232
#1 0x0000555555571a8a in dc_parser_samples_foreach (parser=0x55555565ba80, callback=0x55555556acd9 <sample_cb>, userdata=0x7fffffffd5f0)
at ../../libdivecomputer/src/parser.c:405
#2 0x000055555556c7c7 in dctool_xml_output_write (abstract=0x5555556447b0, parser=0x55555565ba80, data=0x555555667a90 "\020\377\001\241(U", size=78720,
fingerprint=0x555555667a9c "j\234+\311\005F\202\227c2 \034\025\025\024", fsize=4) at ../../libdivecomputer/examples/output_xml.c:530
#3 0x000055555556ab96 in dctool_output_write (output=0x5555556447b0, parser=0x55555565ba80, data=0x555555667a90 "\020\377\001\241(U", size=78720,
fingerprint=0x555555667a9c "j\234+\311\005F\202\227c2 \034\025\025\024", fsize=4) at ../../libdivecomputer/examples/output.c:61
#4 0x000055555556752e in dive_cb (data=0x555555667a90 "\020\377\001\241(U", size=78720,
fingerprint=0x555555667a9c "j\234+\311\005F\202\227c2 \034\025\025\024", fsize=4, userdata=0x7fffffffd930)
at ../../libdivecomputer/examples/dctool_download.c:92
#5 0x00005555555bf3d9 in shearwater_petrel_device_foreach (abstract=0x555555644900, callback=0x555555567383 <dive_cb>, userdata=0x7fffffffd930)
at ../../libdivecomputer/src/shearwater_petrel.c:339
#6 0x000055555557073f in dc_device_foreach (device=0x555555644900, callback=0x555555567383 <dive_cb>, userdata=0x7fffffffd930)
at ../../libdivecomputer/src/device.c:423
#7 0x0000555555567bb7 in download (context=0x5555556468b0, descriptor=0x55555563b030 <g_descriptors+10000>, transport=DC_TRANSPORT_BLUETOOTH,
devname=0x7fffffffe722 "00:13:43:5B:9A:27", cachedir=0x0, fingerprint=0x0, output=0x5555556447b0, limit=0)
at ../../libdivecomputer/examples/dctool_download.c:227
#8 0x0000555555568250 in dctool_download_run (argc=1, argv=0x7fffffffe2a8, context=0x5555556468b0, descriptor=0x55555563b030 <g_descriptors+10000>)
at ../../libdivecomputer/examples/dctool_download.c:360
#9 0x000055555556698a in main (argc=8, argv=0x7fffffffe270) at ../../libdivecomputer/examples/dctool.c:312
Gdb gets a bit confused for some reason, it's actually the line above that if-statement that corrupts the FILE pointer:
struct dc_parser_sensor_calibration_t *out = (struct dc_parser_sensor_calibration_t *)userdata;
out->external_ppo2_used = true;
userdata callback here is the sampledata structure from dctool_xml_output_write.
Something in the needs_divecan_calibration_estimate has some odd assumptions of what userdata contains and just writes to it and everything explodes.
If I just #if 0 out that code I can download with dctool again:
index 10b2f13a..1a65fc4b 100644
--- i/src/shearwater_predator_parser.c
+++ w/src/shearwater_predator_parser.c
@@ -945,6 +945,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
break;
}
+#if 0
struct dc_parser_sensor_calibration_t userdata = { 0 };
dc_status_t rc = shearwater_predator_parser_samples_foreach(abstract, NULL, (void *)&userdata);
@@ -971,6 +972,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
if (!calibrated) {
add_sensor_state(parser, userdata.external_ppo2_used);
}
+#endif
static const char *name = "Divemode";
if (divemode == M_OC_REC) {
@@ -1224,6 +1226,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
if ((status & PPO2_EXTERNAL) == 0) {
double calculated_ppo2 = data[offset + pnf + 6] / 100.0;
+#if 0
if (userdata) {
struct dc_parser_sensor_calibration_t *out = (struct dc_parser_sensor_calibration_t *)userdata;
@@ -1254,6 +1257,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal
out->ppo2_sample_count++;
}
}
+#endif
if ((status & SAMPLE_STATUS_BO_CCR) == 0 && callback) {
sample.ppo2.sensor = DC_SENSOR_NONE;
I had some odd issues downloading from my Petrel 2, so I tried running dctool download directly to better diagnose it, and saw glibc complaining about corrupt FILE* data.
This got me running in circles for a while, but eventually I figured out something corrupted the pointer and debugged what:
Gdb gets a bit confused for some reason, it's actually the line above that if-statement that corrupts the FILE pointer:
userdata callback here is the sampledata structure from dctool_xml_output_write.
Something in the needs_divecan_calibration_estimate has some odd assumptions of what userdata contains and just writes to it and everything explodes.
If I just #if 0 out that code I can download with dctool again: