Skip to content

needs_divecan_calibration_estimate breaks download from normal Petrel 2 with regular analog ppo2 #127

Description

@glance-

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;

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions