(gdb) break *0x972

Debugging, GNU± Linux and WebHosting and ... and ...

HTML Trick: Show Hidden Password

Tuesday, November 04, 2014 - No comments

Have you ever been stuck with password that you web browser knows, but you can't remember it? like that, it's here, but behind the dots ...

The normal way to proceed (in Firefox) in to go to [Preferences|about:preferences] > [Security|about:preferences#security] > Saved passwords, and lookup your password.

The "hacker" way is quicker, but requires a bit of HTML knowledge (but not that much ^^), as well as new web-dev tools, like Firefox's Element Inspector. Right click on your password field, inspect element:

Now you see the source of your web-page. Locate the <input type='password'/> element, and ... delete/edit the field type='password'. That's it ! It's not a password field anymore, so the web-browser doesn't hide it!

Easy peazy :-)


If you're bored with a moving image or text, or an advertisment, you can do the same to get rid of it, that's quite efficient! Just pay attention to what you delete, it's easy to remove the entire page if you delete a top-level element ;-)

Publié dans :  

Working Hard

Friday, October 31, 2014 - No comments

I also actually do work hard, sometimes, as when I took that screenshot of my work environment (it was the second year of my PhD program):



  • i3 window manager tilling the dual-screen
  • Firefox browsing GDB website, certainly looking for its documentation
  • Eclipse IDE opened on first investigations of what would become my PhD contribution
  • GDB running, trying to capture the behavior of Unix sockets,
  • GDB being compiled, as I was also working on its source code
  • (I could have a GDB instance debugging the other GDB, but that would have been to much :-)
  • Emacs editor opened on my literature review LaTeX document
  • Linux kernel configuration panel, as I was building a ARM version to play with ST's Linux kernel debugger
  • Unix top command, to make sure that my system is not overloaded by all of the above!

(maybe the screenshot was a bit staged, in particular the web browser, whereas I was actually looking a way to ... put a subject in a mailto:// link, but not that much ;-)

Publié dans :  

Caught Working Hard

Friday, October 31, 2014 - No comments

I was caught working very hard last June, Google spies are everywhere ^^ (but we saw them, twice, so they're not very good spies!)





to my defense, I must say it's very rare that we had coffee outside, but it was a very nice sunny end-of-spring day!

Publié dans :

Conditional Compiling in Latex based on Filename

Wednesday, October 29, 2014 - 1 comment

If you want to generate two versions of a document, for example one for online reading with hyperlinks and another one for printing, with footnotes instead of hyperlinks [1], you can use this trick:

\usepackage{substr}

\newif\ifPaper
% that inside a package, where I can pass "paper" as an option
\DeclareOption{paper}{\global\Papertrue} 

% if substring "paper" is found in the job (file) name, set the flag
\IfSubStringInString{\detokenize{paper}}{\jobname}{\Papertrue}{} 

then you create a link command accordingly:

\newcommand{\link}[2]{
\ifPaper#1\footnote{\url{#2}}\else\href{#2}{#1}\fi
}

and finally you create a link (symbolic or hard, it doesn't matter) and compile one version or the other:

ln -s myfile.tex myfile-paper.tex
pdflatex myfile
pdflatex myfile-paper

(I guess that some LaTeX packages already do that for free, but conditional compilation can have many other usages.)

1: http://blog.0x972.info/?d=2014/10/29/09/55/15-conditional-compiling-in-latex-based-on-filename

Just a Word about Free Cartography and OpenStreeMap...

Sunday, October 26, 2014 - No comments

Do you know OpenStreeMap? it's an alternative to Google Map that is developed collaboratively. Do you know what it means (for a map)? it means that it grows thanks to its user community, instead of a private (or public) company. It also looks the way the community wants. The first link was the "default" aspect, OpenCycleMap provides an alternative one, oriented towards biking, OpenSeaMap for sailing, hiking maps, etc.

Rendering a map is not an easy task, however populating it is. Indeed, OpenStreetMap is more a database than a drawing (that's why the 'default' rendering is not best). And adding information to the database is easy. Open [OpenStreetMaphttp://www.openstreetmap.org/], go to a place you like and know (very) well, and add what is missing. In rural areas, that can be a road or an entire village, that will be harder!

And the good thing about communities, it's that they're as reactive as they're interested in the project. Take that screenshot for instance:


you see the highway entry in the upper part ? it opened one month ago. See the roundabout? it was build ... maybe half a year ago. Now compare with Google Map:


None of them! What about the (French) National Mapping Institute:



Nope, not better, maybe even worst!

One last thing, the Open Source Routing Machine project adds route computation to OpenStreeMap, [very very useful, quick and efficient|http://map.project-osrm.org/?loc=grenoble&loc=giens| !



Geoportail is the official portal for online IGN maps. They provide great hiking maps, the best you can find for France ... but I feel the default interface tedious to use, slow, un-intuitive, not fullscreen, (based on Flash). But there is an alternative !, and they provide it themselves! It's the mobile version. Just agree that you want to use this version on your computer, switch to Maps (Cartes), and there you are!



And an example of a region I mapped, where my parents live:


You can see clearly on the West side, at the junction of the railway and D80, where I stopped mapping! On the South, the limit is the river, and Est, it's more or less the Route des Granges road.

Publié dans :

Finding a Bug with GDB (and mcGDB)

Saturday, October 25, 2014 - No comments

Yesterday, I had to come back on an OpenCL code I wrote 6 months ago, for a trivial update. After I did my few modification, I ran the code to test it, and it failed.

$ bin/xspecfem3D
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:
#0  0x7FFD9B489BC5
#1  0x4CA9DD in prepare_cleanup_device_ at prepare_mesh_constants_gpu.c:2472
#2  0x40473A in xspecfem3d at specfem3D.F90:473
#3  0x7FFD9930BB44
Segmentation fault

First reflex: run it with GDB:

$ gdb bin/xspecfem3D
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7bd6bc5 in clReleaseMemObject () from /usr/lib/x86_64-linux-gnu/libOpenCL.so.1
(gdb) where
#0  0x00007ffff7bd6bc5 in clReleaseMemObject () from /usr/lib/x86_64-linux-gnu/libOpenCL.so.1
#1  0x00000000004ca9de in prepare_cleanup_device_ () at src/gpu/prepare_mesh_constants_gpu.c:2472
#2  0x000000000040473b in xspecfem3d () at src/specfem3D/specfem3D.F90:473
#3  main () at src/specfem3D/specfem3D.F90:32
#4  0x00007ffff5a58b45 in __libc_start_main () at libc-start.c:287
#5  0x0000000000404780 in _start ()

We can see that the crash is in function clReleaseMemObject, around these lines in the source file:

#ifdef USE_OPENCL
    if (run_opencl) RELEASE_PINNED_BUFFER_OCL (station_seismo_field); // <---- segfault here
#endif
#ifdef USE_CUDA
    if (run_cuda) cudaFreeHost(mp->h_station_seismo_field);
#endif

RELEASE_PINNED_BUFFER_OCL is a preprocessor macro function defined like that:

#define RELEASE_PINNED_BUFFER_OCL(_buffer_) \
     clCheck(clEnqueueUnmapMemObject(mocl.command_queue, mp->h_pinned_##_buffer_, \
                                                           mp->h_##_buffer_, 0, NULL, NULL)); \
     clCheck(clReleaseMemObject (mp->h_pinned_##_buffer_))

Okay, so we crash in that second line. What is the value of [c]cl_mem mp->h_pinned_station_seismo_field[c]? (defined there)

(gdb) print mp->h_pinned_station_seismo_field
$1 = (cl_mem) 0x3fd71113a0000000
(gdb) print *mp->h_pinned_station_seismo_field
$2 = <incomplete type>

The pointer appears to be valid, but we don't know much about it. Let's try to set a breakpoint on the function call before the segfault:

(gdb) break clEnqueueUnmapMemObject
(gdb) run
Program received signal SIGSEGV, Segmentation fault.

Humg? we wanted to stop before the segfault, the application was not supposed to crash. Let's examine a bit further the state of the application when it crashed:

#ifdef USE_OPENCL
   if (run_opencl) RELEASE_PINNED_BUFFER_OCL (station_seismo_field); // <---- segfault here
#endif
#ifdef USE_CUDA
   if (run_cuda) cudaFreeHost(mp->h_station_seismo_field);
#endif

Both USE_OPENCL and USE_CUDA are defined, I know it. run_opencl should be true as well, let's check that:

(gdb) print run_opencl
$1 = 0

Oh oh, waht? so I'm not in an OpenCL run? (OCL and Cuda are mutually exclusive) Let's make sure that we're in Cuda:

(gdb) print run_cuda
$2 = 1

Alright, that's clear now!

* OpenCL was not supposed to run,
* it crashes in clReleaseMemObject nevertheless,
* breakpoint in the first function of the macro-function didn't work, ...

The if test is not doing what was expected from it! Here is what it really does:

if (run_opencl) clCheck(clEnqueueUnmapMemObject(mocl.command_queue, mp->h_pinned_station_seismo_field, 
                                                           mp->h_station_seismo_field, 0, NULL, NULL)); 
     clCheck(clReleaseMemObject (mp->h_pinned_station_seismo_field));

The second function call is not part of the conditional execution ...



The problem is easy to solve, either by protecting the if:

if (run_opencl) {
    RELEASE_PINNED_BUFFER_OCL (station_seismo_field);
}

or by protecting the macro:

#define ALLOC_PINNED_BUFFER_OCL(_buffer_, _size_) do { ....} while (0)

I originally didn't protect the macro, because all my ifs are protected (and I didn't paid enough attention at being future-proof). But the code isn't mine, and someone changed the coding convention (and didn't test the OpenCL branch of the code).



In mcGDB, understanding the state of the application would have been easier. Instead of:

(gdb) print mp->h_pinned_station_seismo_field
$1 = (cl_mem) 0x3fd71113a0000000
(gdb) print *mp->h_pinned_station_seismo_field
$2 = <incomplete type>
The pointer appears to be valid, but we don't know much about it.


we could have had:

(mcGDB) opencl info buffer mp->h_pinned_station_seismo_field
No OpenCL buffer at @0x....

and instead of: run_opencl should be true as well, let's check that:

(gdb) print run_opencl
$1 = 0


we would have noticed that no OpenCL event was displayed in the debugger before the crash (like "New kernel created", "New buffer created"), or more explicitely:
(mcgdb) opencl show activity
No OpenCL activity recorded

Adblock et la Publicité ...

Thursday, October 23, 2014 - No comments

Que ce soit en ville (Arnaud Gaillard / wikimedia),


  • à la TV
  • une page sur deux dans les journaux
  • à la radio, genre **ça** (la pub Matmut avec Chevalier/Laspales), et c'est l'exemple le plus representatif qu'on puisse trouver simplement ...

la pub est chiante ! Et c'est pas une critique, c'est un constat. Il faut qu'on la garde en tète, qu'on pense à eux, c'est tout. Et tous les arguments sont bons pour ça, couleurs flashs, musique simple répétitive, augmentation du volume sonore. C'est assez irrespectueux, ça utilise des faiblesses pour faire passer de mauvais arguments.... enfin vous connaissez tous, ce n'est pas de ça dont je veux discuter.

Là où je veux en venir, c'est que dans ces média, la pub est imposée. On a beau baisser le son de la radio, ou prendre un casse-croûte pendant la pub TV, on ne peut pas y faire grand chose.
Sur Internet c'est différent. Sur un ordi, on peut tout contrôler, à condition d'avoir un peu de connaissances, des logiciels libres (j'en reparlerai), et de la bonne volonté (parce qu'il faut prendre le temps de s'habituer aux logiciels libres).

En l’occurrence, Firefox et AdBlock (entre autres). AdBlock va simplement dire a Firefox de ne pas charger les images qui proviennent de certains sites. C'est pas plus compliqué que ça ! Après toute l’efficacité dépend de la liste des sites qu'on va bloquer, mais c'est un autre problème.


Quand je vois des sites qui expliquent que les bloqueurs de pub cassent leur source de revenu, je repense a toutes les pubs qui nous sont matraquées sans qu'on puisse y faire quoi que ce soit, et je remercie l'informatique de nous donner des moyens de les bloquer !



Il y a quand même quelques exceptions, comme les pubs au cinéma, qui sont assez souvent des mini-films avec de beaux paysages, ou celles de Nespresso, ou sur Internet, des pubs non-intrusives qui sont autorisées par défaut (je crois) dans AdBlock, comme sur Reddit ou Google. On finit donc bien par trouver un terrain d'entente, quand on a les moyens de se faire entendre (l'argent du cinéma / les bloqueurs de pubs).

Callstack from Userland to Kernel-space

Monday, October 20, 2014 - No comments


When I started my PhD 4 years ago, I had the chance to play with a nice tool (but ST internal ...) that does advanced Linux kernel debugging. Among its capabilities, one thing that astonished me was the ability to show a full call stack, from userland down to kernel-space :

                      #0  context_switch ()       at kernel/sched.c:2894
                      #1  schedule ()             at kernel/sched.c:5500
                      #2  do_nanosleep ()         at kernel/hrtimer.c:1494
                      #3  hrtimer_nanosleep ()    at kernel/hrtimer.c:1563
                      #4  sys_nanosleep ()        at kernel/hrtimer.c:1601
                      #5  ret_fast_syscall ()     at arch/arm/kernel/entry-armv.S:744

                      #6  nanosleep ()            at lib/nanosleep.c:51
                      #7  sleep ()                at unix/sysv/linux/sleep.c:138
                      #8  main ()                 at sleep.c:4

That may look trivial at the first sight, but the top part of the stack (#0 - #5) belongs to the kernel (Linux), whereas the bottom part belong to user-space. Frame #8 is the application itself, and #7/#6 the libc.
Generating such a trace is impossible in a standard environment, as the kernel runs in a protected memory area, that is not address the same way as userland.

This particular example comes from a work I did, where I had to port the low-end of the kernel debugger to support ARM processors running on Qemu virtual machine. I studied the __copy_to/from_user() kernel functions to understand how the kernel does to lookup userland addresses from kernel space, and reimplemented the same logic inside the debugger.

As far as I remember, that involved modifying the registers of the machine's MMU, which is the unit in charge of mapping virtual addresses to physical ones. So the debugger had to reprogram it with the memory context of the current process, ask Qemu to convert the address, and reinstall the original process (otherwise ... system crash and kernel panic!).



* Attentive readers may have noticed that, unfortunately, this is not the complete stack, ~half of it is still missing! The callstack doesn't start magically from the
main
function ... With gdb
set backtrace past-main on
and
set backtrace past-entry on
we can see what happened before the
main
(that is, in the
libc
), but we won't be able to get past that today ...

#3  0x00000000004018ed in main () at src/sleep.c:145
#4  0x0000003d49221d65 in __libc_start_main () at libc-start.c:285
#5  0x00000000004019f9 in _start ()

Add notification support to Owncloud Calendar with Selfloss (RSS aggregator)

Saturday, October 18, 2014 - No comments

In my different steps toward self-hosting, I switched from Google Calendar to Owncloud Calendar. However, one neat feature is missing in Owncloud, it's the ability to set task reminders. My schedule is not very busy, so I mainly put 'far-off' meetings and appointments ... and I forget to check the calendar again and miss the event!

One thing I check daily is my mail client, the other is my RSS feed aggregator, selfoss. And
selfoss
appears to be easily expendable, so the idea grew quickly in my mind, and today it's ready: I need to export the calendar in ICS format, parse it, and feed it to selfoss. I first thought about converting it to RSS, but I didn't want my events to be available online, so it was easier and quicker to jump directly from Owncloud to Selfoss.

Owncloud is open-source, so finding how to export the calendar was just a matter of code study, hopefully not done by myself this time:

define('OCROOT', '$PATH_TO_OWNCLOUD/owncloud/');

function owncloud_get_calendar($username, $cal_id) {
  //it's not necessary to load all apps
  $RUNTIME_NOAPPS = true;
  require_once(OCROOT . '/lib/base.php');
  require_once(OCROOT . '/apps/calendar/appinfo/app.php');
  
  //set userid
  OC_User::setUserId($username);
  
  OCP\User::checkLoggedIn();
  OCP\App::checkAppEnabled('calendar');
  
  $calendar = OC_Calendar_App::getCalendar($cal_id, true, true);
  if(!$calendar) {
    return;
  }
  
  return OC_Calendar_Export::export($cal_id, OC_Calendar_Export::CALENDAR);
}

The
cal_id
parameter is show in Owncloud calendar when you try to download the ICS file:


ICS is a well-define format, same luck, it wasn't hard to find a simple parser: ics-parser.

Last step, and not least one, I had to feed to parsed ICS to Selfoss, through a "spout", a source plugin able to a provide new items to Selfoss.

  • first, we tell selfoss what information we need to add a new calendar feed: the URL is mandatory, username and password are optional, "days in advance" tells for how many days in advance we want to fetch the events.

public $params = array(
        "url" => array(
            "title"      => "URL",
            "type"       => "text",
            "default"    => "",
             "required"   => true,
            "validation" => array("notempty")
       ),
        "username" => array(
            "title"      => "Username",
            "type"       => "text",
            "default"    => "",
            "required"   => false,
            "validation" => ""
       ),
        "password" => array(
            "title"      => "Password",
            "type"       => "password",
            "default"    => "",
            "required"   => false,
            "validation" => ""
       ),
        "days" => array(
            "title"      => "Days in advance",
            "type"       => "text",
            "default"    => "-1",
            "required"   => false,
            "validation" => "int"
       )
   );

  • then we load the calendar, either from Owncloud or directly from its URL. If URL is "owncloud_", we load from owncloud, otherwise, we fetch the URL. Spouts implement the iterator interface, so here we prepare iterator, "rewind" it, and it's ready.

    public function load($params) {
      $link = $params['url'];
      if (strpos($link, "owncloud_") === 0) { // owncloud_<cal_id>
        $calendar_lines = owncloud_get_calendar($params['username'],
                                                substr($link, 1+strpos($link, "_")));

        $ical = new ICal(null, explode("\n", $calendar_lines));
      } else {
        if (!empty($params['password']) && !empty($params['username'])) {
          $auth = $params['username'].":".$params['password']."@";
          $link = str_replace("://", "://$auth", $link);
        }

        $ical = new ICal($link);
      }
      
      $this->items = $ical->events();
      
      $this->days = $params['days'];
      $this->rewind();

      $this->params = $params;
    }

  • next this it to select the which events we want to return to Selfoss, in the
    next
    other of the iterator. We count the distance in days, and only print it if it's below the threshold. Obviously, we also discard the past events.

    public function next() {
      if ($this->items == false) {
        return false;
      }
      while (1) {
        $this->position++;

        $event = $this->current_event();
        if (!$event) {
          return false;
        }
        
        $event_date = strtotime($event["DTSTART"]);
        $daydiff = floor(($event_date - time()) / 60 / 60 / 24); // in days
          
        if (isset($event["RRULE"])) { // repeating event
          // explained at the step

        } else { // normal event
          if ($event_date < time()) { // not in the past
            continue;
          }
        }
        if ($this->days !== -1 && $daydiff > $this->days) { // not more than $days of distance
          continue;
        }
        $this->items[$this->position]["DDIST"] = $daydiff;

        return $this->current();
      }
    }

  • one kind of events were missing after the first try, it's the repeating events: "every Saturdays, starting the 18th of october". So far I only implemented weekly events, I'll add other kinds whenever I'll need them!

       if (isset($event["RRULE"])) { // repeating event
          if ($event["RRULE"]["FREQ"] === "WEEKLY") {
            if ($event["RRULE"]["INTERVAL"] !== "1") {
              //ignore for now
              continue;
            }
            $DAYS_OF_WEEK = array("SU" => 0, "MO" => 1, "TU" => 2, "WE" => 3, "TH" => 4, "FR" => 5, "SA" => 6);
            $daydiff = $DAYS_OF_WEEK[$event["RRULE"]["BYDAY"]] - date("w");
            if ($daydiff < 0) $daydiff += 7;
            
          } else {
            // ignore for now
            continue;
          }
     }

  • the last step was providing Selfoss with the events/items:

    public function getTitle() {
      if ($this->items == false || !$this->valid()) {
        return false;
      }
      
      $event = $this->current_event();
      if (isset($event["RRULE"])) {
        $dispdate = repeating_time($event["RRULE"]) . " " . end_time($event["DTSTART"]);
      } else {
        $dispdate = start_time($event["DTSTART"]);
      }
      $dispdate .= " -> " . end_time($event["DTEND"]);
      
      $text = stripslashes(htmlentities($event["SUMMARY"]));

      return "$dispdate | $text";
    }

    public function getContent() {
        if ($this->items == false || !$this->valid()) {
          return false;
        }
        
        $event = $this->current_event();
            
        $text = stripslashes(htmlentities($event["SUMMARY"]));
        
        $description = "";
        if (isset($event["DESCRIPTION"])) {
          $description = $event["DESCRIPTION"];
        }
        if (isset($event["LOCATION"])) {
          $description .= "\nLocation: ".htmlentities($event["LOCATION"]);
        }

        if ($event["DDIST"] === 0) {
	  $description .= "\nAujourd'hui";
	} else {
          $description .= "\nDans ".$event["DDIST"]. " jour";
          
          if ($disttime !== 1) {
            $description .= "s";
          }
        }

        $description = str_replace("<br>", "\n", htmlentities($description));
        
        return $description;
    }

    public function getId() {
      if ($this->items == false || !$this->valid()) {
        return false;
      }
       
      $id = $this->current_event()["UID"];
      $id .= date("Y-m-d"); // refresh the event every day

      if (strlen($id) > 255) {
        $id = md5($id);
      }
      return $id;
    }

You can see in
getId
that I concatenate the date of the day to the event ID. That means that every day, Selfoss will "think" that the event is new, and mark it as unread ... and there we are !


Actually, there is one more step I had to implement: my Selfoss feeds are public, I don't mind sharing what I read, but I don't want my calendars to be publicly available. So I hacked Selfoss to "hide" some items if the session is not authenticated. Easiest way: hide tags starting with a "@". Nothing very complicated, we just remove the unwanted tags from the lists !

- return $this->backend->get($options);
+ $items = $this->backend->get($options);
+
+ if(!\F3::get('auth')->showHiddenTags()) {
+ foreach($items as $idx => $item) {
+ if (strpos($item['tags'], "@") !== false) {
+ unset($items[$idx]);
+ }
+ }
+ $items = array_values($items);
+ }
+
+ return $items;

(and the same for sources, tags and items)

And there we are, daily notification of Owncloud calendar events, directly in my feed reader :-)

Publié dans :  

C'est quoi le debugging, en fait ?

Friday, October 17, 2014 - No comments



Une thèse sur le debugging de machin truc, c'est bien, mais si on ne sait pas ce que c'est du debugging, ça n'avance pas beaucoup. Pourtant ce n'est pas uniquement de l'informatique ... Un exemple :

J'ouvre le frigo et la lumière ne s'allume pas. C'est un bug !
Il faut maintenant résoudre ce problème. Quelles peuvent-être les causes ?

  • 1) l'ampoule est grillée
  • 2) l'interrupteur de la porte de s'active pas
  • 3) le frigo n'est pas branché
  • 4) il n'y a pas d'électricité dans la maison
  • -1) une brique de lait cache l'ampoule
  • 0) il y a trop de lumière dans la maison pour distinguer la lumière du frigo

les causes -1 et 0, c'est l'utilisateur qui s'y prend mal, on y peut rien ==> PEBCAK : Problem exists between chair and keyboard, en français problème avec l'interface chaise-clavier :-)

  • pour 1) ce n'est pas facile à tester, suivant !
  • pour 2) on appuie manuellement sur l’interrupteur, est-ce que ça marche ?
  • pour 3) on regarde si la prise est branchée
  • pour 4) on allume une lumière dans la maison

Ça devrait être suffisant pour cerner le problème.
1/ et 2/ ce sont des problèmes mineurs, non prioritaires.
3/ et 4/ sont plus critiques. Est-ce que c'est grave ?

* 5/ est-ce que le frigo/congel sont toujours froid ?

C'est l'application de la méthode scientifique ! On fait des hypothèses qui pourraient expliquer notre observation, des expérimentations pour les tester, et on tire des conclusions de ces résultats.

Le problème du frigo, c'était cet été, en arrivant en vacances ;-)



En informatique, c'est pareil. Enfin ... sauf que les problèmes ne sont pas toujours aussi simple à décrire, les hypothèses pas faciles à formuler, et les expérimentations pas faciles à réaliser !

Déjà, les programmes ont un état interne (les 4Go de RAM de l'ordi principalement, mais aussi les fichiers du disque dur). On n'a pas beaucoup d'exemple de systèmes à état interne dans la vie de tous les jours, c'est dur de trouver un exemple non informatique ...

On peut prendre ... un enfant qui apprend ! On part de zéro, aucune connaissance (faut pas extrapoler l'exemple hein, c'est juste un support !).

  1. Maternel, on apprend la vie en communauté
  2. Élémentairement, on apprend 1/ le français, 2/ les maths
  3. Collège, on apprend l'anglais à la suite du français, en on renforce les maths
  4. ==> How you solve x = 5x² + 3x + 10 for x ? heu ... se sé pas !

Eh oui, ça bug ! Des hypothèses ?

  • parle pas anglais
  • sait pas résoudre d'équation
  • sourd ! (oui, faut penser à tout :-)

Comment on peut tester ça ? on peut voir s'il parle anglais, pour comprendre la question, ... mais si nous, on ne parle pas anglais ? (on peut voir s'il parle français, si non, il ne peut pas avoir appris l'anglais).
Mais et s'il a planté ? si on a seulement sa feuille d'exercice ? Et ben il faut faire une thèse pour construire de nouveaux outils !



Ces outils, ça peut être un voltmètre pour mesurer la tension aux bornes de l'ampoule du frigo. C'est réaliste cet exemple de voltmètre/ampèremètre/ohmmètre , parce que ça ressemble assez à ce que je fais : on se branche sur un circuit, les outils nous permettent d'observer des paramètres "invisibles" à l’œil nu. C'est du debugging interactif.

Ça peut être aussi le dossier de suivi de l'élève, avec des nôtres prises chaque trimestre, on peut savoir comment s'est déroulée son éducation (à condition d'aller à lire ce que les enseignants ont écrits !). C'est moins mon domaine ça, c'est de l'analyse de trace.

On peut aussi valider à l'avance le programme des enseignements qu'il doit obligatoirement suivre pour être sur de réussir notre test (c'est plus facile en informatique qu'en vrai ça ;-).



Et pour expliquer ma thèse, on peut prendre un dernier exemple.

On se place dans un contexte industriel particulier, par exemple, deux équipes de foot (= une application multicœur) qui doivent faire un match.
Les deux équipes, c'est des applications, et les joueurs, des processeurs.

Dans l'état actuelle de la science, on peut regarder une personne*, suivre ses déplacements, écouter ce qu'elle dit.
On peut aussi regarder plusieurs personnes d'une équipe, mais on regardera chaque personne indépendamment, sans notion d'équipe ou de collaboration.

Essaies de comprendre un match en ne regardant qu'un joueur à la fois ! S'il a le ballon, oui c'est bien, mais il fait une passe. Il faut que tu passes tous les autres joueurs en revu pour voir s'ils on le ballon.
Essaies de comprendre pourquoi Machin a fait la passe à Untel, si tu ne connais pas la tactique de jeu, ni la position du ballon ...

Ma contribution, c'est de montrer qu'on peut faire des outils (et qu'ils sont utiles !) qui vont connaitre les règles du jeu (du foot, du rugby, du hand). Au lieu de montrer des bonshommes qui bougent dans tous les sens sur une pelouse, l'outil montrera des joueurs, avec des numéros, des rôles, des tactiques de jeu, et un ballon. Au lieu de voir une personne qui courre bizarrement et tombe, puis une autre qui se met à faire, on verra un footballer qui drible, se fait tacler et prendre le ballon. Au lieu d’écouter une personne parler toute seule (50% du dialogue), on verra qu'elle échange avec un autre joueur et qu'ils se mettent d'accord sur la prochaine action.

C'est du model-centric debugging for multicore embedded systems !

* une fois, mais est-ce qu'on ne peut déboguer 1000 fois 1000 personnes ?